ECON 494 - Spatial Data Science Project

Our project aimed to analyze the Ukraine conflict using spatial analysis and maps generated through data from ACLED (Armed Conflict Location & Event Data Project). Focusing on the violence targeting civilians after invasion of Russia into Ukraine, we utilized R programming to extract and visualize the conflict data, enabling us to present a comprehensive overview of the events and their spatial distribution.

library(sp)
library(raster)
library(ggplot2)
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:raster’:

    intersect, select, union

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(tidyverse)
── Attaching core tidyverse packages ─────────────────────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ lubridate 1.9.2     ✔ tibble    3.2.1
✔ purrr     1.0.1     ✔ tidyr     1.3.0
✔ readr     2.1.4     ── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ tidyr::extract() masks raster::extract()
✖ dplyr::filter()  masks stats::filter()
✖ dplyr::lag()     masks stats::lag()
✖ dplyr::select()  masks raster::select()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(conflicted)

Introduction

  • Russia invaded Ukraine in February 2022, resulting in the highest levels of political violence recorded in a single country by ACLED.

  • Civilians in Ukraine have faced shelling, indiscriminate strikes, deliberate attacks, and harsh treatment in occupied areas.

  • Russian forces targeted Kyiv but retreated in northern Ukraine while quickly seizing territories in southern and eastern regions.

  • Over 5,000 reported civilian fatalities have occurred, but the actual toll is likely much higher.

  • Different regions of Ukraine experienced varying levels of violence and occupation during the conflict.

#ukraine_states_rds <- raster::getData('GADM', country = "UKR", level = 1)
ukraine_states_rds = readRDS("ukraine.rds") #https://gadm.org/download_country.html
ukraine_map <- ggplot() +
  geom_polygon(data=ukraine_states_rds,  aes(x = long, y = lat, group = group, fill = id), fill="orange", alpha = 0.6 ) + guides(fill = "none")
Regions defined for each Polygons
ukraine_map

east_ukraine_states_rds_names <- list("Dnipropetrovs'k", "Donets'k", "Luhans'k" ,  "Kharkiv", "Zaporizhzhya")

east_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% east_ukraine_states_rds_names)
south_ukraine_states_rds_names <- list("Chernihiv", "Kiev", "Kiev City", "Zhytomyr", "Sumy")
south_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% south_ukraine_states_rds_names)
central_ukraine_states_rds_names <- list("Cherkasy", "Kirovohrad", "Poltava", "Vinnytsya")
central_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% central_ukraine_states_rds_names)
western_ukraine_states_rds_names <- list("Volyn", "Chernivtsi", "Ivano-Frankivs'k", "Khmel'nyts'kyy", "Rivne", "L'viv", "Ternopil'", "Transcarpathia")
western_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% western_ukraine_states_rds_names)
southern_ukraine_states_rds_names <- list("Crimea", "Kherson",  "Mykolayiv", "Odessa")
southern_ukraine_states_rds <- subset(ukraine_states_rds, NAME_1 %in% southern_ukraine_states_rds_names)
ukraine_map2 <- ukraine_map + 
  geom_polygon(data=east_ukraine_states_rds,  aes(x = long, y = lat, group = group), fill="red", alpha=0.2, color="black") +
  geom_polygon(data=south_ukraine_states_rds,  aes(x = long, y = lat, group = group), fill="black", alpha=0.2, color="black") +
  geom_polygon(data=central_ukraine_states_rds,  aes(x = long, y = lat, group = group), fill="darkblue", alpha=0.4, color="black") +
  geom_polygon(data=western_ukraine_states_rds,  aes(x = long, y = lat, group = group), fill="lightblue", alpha=0.2, color="black") +
  geom_polygon(data=southern_ukraine_states_rds,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black")
Regions defined for each PolygonsRegions defined for each PolygonsRegions defined for each PolygonsRegions defined for each PolygonsRegions defined for each Polygons
ukraine_map2

centroid <- ukraine_states_rds$centroid <- coordinates(ukraine_states_rds)
ukraine_states_rds_names <- ukraine_states_rds$NAME_1
ukraine_map3 <- ukraine_map2 + 
  geom_text(aes(x = centroid[, 1], y = centroid[, 2], label = ukraine_states_rds_names), size=2) + labs(title = "Regions of Ukraine", fontface="bold") + theme_void() + theme(plot.title = element_text(hjust = 0.5, face = "bold")) +  coord_map(projection = "albers", lat0 = 49, lat1 = 54)
ukraine_map3

Conflict Data (ACLED)

eastern_ukraine_states_names = list("Dnipropetrovsk", "Luhansk", "Donetsk", "Kharkiv", "Zaporizhia")
conflict <- read_csv('ukraine.csv', show_col_types = FALSE)
conflict$event_date <- as.Date(conflict$event_date, format = "%d %B %Y")
unique(conflict$admin1)
 [1] "Dnipropetrovsk"  "Luhansk"         "Donetsk"         "Kharkiv"         "Kherson"         "Sumy"            "Zaporizhia"     
 [8] "Kyiv City"       "Chernihiv"       "Crimea"          "Chernivtsi"      "Ivano-Frankivsk" "Khmelnytskyi"    "Lviv"           
[15] "Mykolaiv"        "Odesa"           "Poltava"         "Vinnytsia"       "Kirovograd"      "Zhytomyr"        "Ternopil"       
[22] "Cherkasy"        "Kyiv"            "Volyn"           NA                "Rivne"           "Zakarpattia"    
unique(conflict$event_type)
[1] "Explosions/Remote violence" "Battles"                    "Strategic developments"     "Violence against civilians"
[5] "Protests"                   "Riots"                     
unique(conflict$sub_event_type)
 [1] "Shelling/artillery/missile attack"   "Armed clash"                         "Air/drone strike"                   
 [4] "Remote explosive/landmine/IED"       "Disrupted weapons use"               "Other"                              
 [7] "Agreement"                           "Attack"                              "Arrests"                            
[10] "Change to group/activity"            "Looting/property destruction"        "Non-state actor overtakes territory"
[13] "Abduction/forced disappearance"      "Peaceful protest"                    "Protest with intervention"          
[16] "Government regains territory"        "Sexual violence"                     "Suicide bomb"                       
[19] "Grenade"                             "Non-violent transfer of territory"   "Mob violence"                       
[22] "Excessive force against protesters"  "Headquarters or base established"    "Violent demonstration"              

Apparent War Crimes in Northern Ukraine

In northern Ukraine, ACLED records over 400 incidents targeting civilians, with a significant number occurring during the Russian advance and subsequent occupation. Shelling, artillery, and missile attacks were the most common types of violence, but direct attacks on civilian populations resulted in the highest number of reported civilian fatalities. Mass graves were discovered following the Russian retreat. The Kyiv region, including the city of Kyiv, was most affected by these strikes, while the Sumy region continued to suffer from strikes along its border areas with Russia throughout the year. Incidents related to accidental detonation of mines and explosives continued to occur during and after the invasion. ACLED records at least 43 such events resulting in at least 34 reported fatalities, with the highest incidence in April and May 2022 in the Kyiv and Chernihiv regions following the Russian withdrawal.

filtered_data <- conflict %>%
  dplyr::filter(event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                civilian_targeting!="")
filtered_data <- filtered_data[filtered_data$admin1 %in% c("Zhytomyr", "Kyiv City", "Kyiv", "Sumy", "Chernihiv"),]
filtered_data$month_year <- format(filtered_data$event_date, "%B-%Y")
eastern <- filtered_data[filtered_data$admin1 %in% c("Dnipropetrovsk", "Donetsk", "Kharkiv", "Luhansk", "Zaporizhia"),]
eastern$month_year <- format(eastern$event_date, "%B-%Y")
# Create a new column called 'new_event_type'
filtered_data$new_event_type <- NA

# Map values based on 'sub_event_type'
filtered_data$new_event_type[filtered_data$sub_event_type %in% c("Remote explosive/landmine/IED", "Attack", "Air/drone strike", "Shelling/artillery/missile attack")] <- filtered_data$sub_event_type[filtered_data$sub_event_type %in% c("Remote explosive/landmine/IED", "Attack", "Air/drone strike", "Shelling/artillery/missile attack")]
filtered_data$new_event_type[!(filtered_data$sub_event_type %in% c("Remote explosive/landmine/IED", "Attack", "Air/drone strike", "Shelling/artillery/missile attack"))] <- "Other violence"
ggplot(filtered_data, aes(x = month_year, fill = new_event_type, )) +
  geom_bar(position = "stack") +
  labs(x = "Date", y = "Number of Events", title = "Violence Targeting Civilians in Northern Ukraine",
       subtitle = "February 2022 - January 2023",
       fill = "Sub-Event Type") +
  theme_bw()

# Convert month_year column to proper date format
filtered_data$month_year <- as.Date(paste0("01-", filtered_data$month_year), format = "%d-%B-%Y")

# Sort the data by the month_year column
filtered_data <- filtered_data[order(filtered_data$month_year), ]


# Create the bar chart
ggplot(filtered_data, aes(x = month_year, fill = new_event_type, )) +
  geom_bar(position = "stack") +
  labs(x = "Date", y = "Number of Events", title = "Violence Targeting Civilians in Northern Ukraine",
       subtitle = "February 2022 - January 2023",
       fill = "Sub-Event Type") +
  theme_bw()

# Convert month_year column to proper date format
eastern$month_year <- as.Date(paste0("01-", eastern$month_year), format = "%d-%B-%Y")

# Sort the data by the month_year column
eastern <- eastern[order(eastern$month_year), ]


# Create the bar chart
ggplot(eastern, aes(x = month_year, fill = admin1, )) +
  geom_bar(position = "stack") +
  labs(x = "Date", y = "Number of Events", title = "Violence Targeting Civilians in Eastern Ukraine",
       subtitle = "February 2022 - January 2023",
       fill = "Region") +
  theme_bw()

Heavy Fighting Along the Frontline in Eastern Ukraine

Eastern Ukraine faces unprecedented violence, with three-quarters of political violence events occurring in the region, primarily due to shelling, artillery, and missile attacks. Despite relative distance from the frontline, the Dnipropetrovsk region remains at risk, as Russia continues air and missile strikes, exemplified by the deadly incident in Dnipro on 14 January 2023.

Political Violence in Eastern Ukraine

Eastern parts of eastern Ukraine has been highly contested since the beginning of the invasion. The eastern portion of the Kharkiv region, which was occupied by Russian forces, served as a base for their offensives in the Luhansk and Donetsk regions. The Luhansk region experienced intense violence between late February and mid-summer 2022, as Russian forces captured towns by destroying them with artillery. A similar approach was employed in the spring of 2022 to capture Mariupol, the last Ukrainian stronghold in the southern Donetsk region, resulting in dire consequences for both trapped Ukrainian military personnel and civilians. The Zaporizhia region experienced relatively lower levels of armed violence due to Russia’s swift occupation in late February and early March 2022.

conflict_eastern_ukraine <- conflict %>%
  dplyr::filter(
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                event_type %in% c("Explosions/Remote violence", "Battles", "Violence against civilians"),
                admin1 %in% eastern_ukraine_states_names)
event_counts_eastern_ukraine <- conflict_eastern_ukraine %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), event_type)
east_ukraine_states_rds
class       : SpatialPolygonsDataFrame 
features    : 5 
extent      : 32.96244, 40.21807, 46.07875, 50.46491  (xmin, xmax, ymin, ymax)
crs         : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 10
Warning: no non-missing arguments, returning NAWarning: no non-missing arguments, returning NAWarning: no non-missing arguments, returning NAWarning: no non-missing arguments, returning NA
names       : GID_0,  NAME_0,    GID_1,          NAME_1,                                                                                      VARNAME_1, NL_NAME_1,  TYPE_1, ENGTYPE_1, CC_1, HASC_1 
min values  :   UKR, Ukraine, UKR.15_1, Dnipropetrovs'k,                                                                 Charkow|Jarkov|Karkov|Khar'kov,        NA, Oblast',    Region,   NA,  UA.DP 
max values  :   UKR, Ukraine,  UKR.8_1,    Zaporizhzhya, Saporoshje|Zaporizhia|Zaporiz'ka Oblast'|Zaporojie|Zaporozhskaya Oblast'|Zaporozh'ye|Zaporožje,        NA, Oblast',    Region,   NA,  UA.ZP 
eastern_ukraine_map <- ggplot() +
  geom_polygon(data=east_ukraine_states_rds,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
eastern_ukraine_map

centroid <- east_ukraine_states_rds$centroid <- coordinates(east_ukraine_states_rds)
centroid[2] = centroid[2]+0.4
centroid[7] = centroid[7]-0.4
centroid[3] = centroid[3]-0.4
text <- geom_text(data = , aes(x = centroid[, 1], y = centroid[, 2], label = c("Dnipropetrovsk", "Donetsk", "Kharkiv", "Luhansk", "Zaporizhia")), color = "black", size = 4)
eastern_ukraine_map +
  geom_point(data = event_counts_eastern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, color=event_type)) +
  geom_point(color="black", shape=21, data = event_counts_eastern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, fill=event_type)) +
  scale_size_continuous(range = c(0.1, 5)) +
  labs(color = "Event Type", size = "Number of Events") +
  labs(title = "Political Violence in Eastern Ukraine", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5), plot.subtitle = element_text(hjust = 0.5)) +
  text

Conflict in Kharkiv

Despite failing to break Ukrainian defenses in and around Kharkiv city, Russian forces had taken control of the majority of the northern and eastern parts of the region by April 2022, including the strategically important transport hub of Izium. However, Ukraine managed to liberate almost the entire region in an unexpected counter-offensive in September 2022. Among the more than 800 incidents targeting civilians, approximately three-quarters involved artillery, missiles, and airstrikes, which also accounted for the majority of reported civilian deaths in the region. Around one-third of these incidents occurred in March 2022 alone.

conflict_kharkiv <- conflict %>%
  dplyr::filter(
                civilian_targeting != "",
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                admin1 == "Kharkiv")
# Create a new column called 'new_event_type'
conflict_kharkiv$new_event_type <- NA

# Map values based on 'sub_event_type'
conflict_kharkiv$new_event_type[conflict_kharkiv$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Remote explosive/landmine/IED", "Attack")] <- conflict_kharkiv$sub_event_type[conflict_kharkiv$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Remote explosive/landmine/IED", "Attack")]
conflict_kharkiv$new_event_type[!(conflict_kharkiv$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Remote explosive/landmine/IED", "Attack"))] <- "Other violence"
number_of_events_kharkiv <- conflict_kharkiv %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), new_event_type)
kharkiv <- subset(ukraine_states_rds, NAME_1 == "Kharkiv")
kharkiv_map <- ggplot() +
  geom_polygon(data=kharkiv,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
kharkiv_map

kharkiv_map +
  geom_point(data = number_of_events_kharkiv, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
  geom_point(color="black", shape=21, data = number_of_events_kharkiv, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
  scale_size_continuous(range = c(0.1, 10)) +
  labs(color = "Sub-Event Type", size = "Number of Events") +
  labs(title = "Violence targeting Civilians in Kharkiv", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Conflict in Luhansk

The extensive use of artillery, missiles, and airstrikes, along with intense close combat, resulted in significant suffering for the civilian population in the Luhansk region. Tragic incidents occurred, such as the shelling of a nursing home in Kreminna on March 11, 2022, which reportedly led to the death of 56 elderly patients. Additionally, an airstrike on a school used as a shelter in Bilohorivka on May 7, 2022, resulted in the loss of at least 60 lives. The shelling of Severodonetsk in March and May 2022 also claimed the lives of over 50 civilians. After the Russian occupation of the region in the summer of 2022, there was a significant decrease in reports of civilians being targeted, although the region has remained highly volatile, particularly since autumn.

conflict_luhansk <- conflict %>%
  dplyr::filter(
                civilian_targeting != "",
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                admin1 == "Luhansk")
# Create a new column called 'new_event_type'
conflict_luhansk$new_event_type <- NA

# Map values based on 'sub_event_type'
conflict_luhansk$new_event_type[conflict_luhansk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Attack")] <- conflict_luhansk$sub_event_type[conflict_luhansk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Attack")]
conflict_luhansk$new_event_type[!(conflict_luhansk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Attack"))] <- "Other violence"
number_of_events_luhansk <- conflict_luhansk %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), new_event_type)
luhansk <- subset(ukraine_states_rds, NAME_1 == "Luhans'k")
luhansk_map <- ggplot() +
  geom_polygon(data=luhansk,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
luhansk_map

luhansk_map +
  geom_point(data = number_of_events_luhansk, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
  geom_point(color="black", shape=21, data = number_of_events_luhansk, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
  scale_size_continuous(range = c(0.1, 10)) +
  labs(color = "Sub-Event Type", size = "Number of Events") +
  labs(title = "Violence targeting Civilians in Luhansk", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Conflict in Donetsk

ACLED data documents more than 16,000 incidents in the Donetsk region, with over 12,000 of them involving shelling, artillery, missiles, and airstrikes. Only a relatively small number of these incidents, around 800, specifically targeted civilians. Prior to the Russian occupation, the city of Mariupol witnessed multiple incidents resulting in significant casualties. Mass casualty events caused by long-range missile and artillery strikes were reported in various areas of the region, affecting both sides of the line of contact.

conflict_donetsk <- conflict %>%
  dplyr::filter(
                civilian_targeting != "",
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                admin1 == "Donetsk")
# Create a new column called 'new_event_type'
conflict_donetsk$new_event_type <- NA

# Map values based on 'sub_event_type'
conflict_donetsk$new_event_type[conflict_donetsk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")] <- conflict_donetsk$sub_event_type[conflict_donetsk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")]
conflict_donetsk$new_event_type[!(conflict_donetsk$sub_event_type %in% c("Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED"))] <- "Other violence"
number_of_events_donetsk <- conflict_donetsk %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), new_event_type)
donetsk <- subset(ukraine_states_rds, NAME_1 == "Donets'k")
donetsk_map <- ggplot() +
  geom_polygon(data=donetsk,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
donetsk_map

donetsk_map +
  geom_point(data = number_of_events_donetsk, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
  geom_point(color="black", shape=21, data = number_of_events_donetsk, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
  scale_size_continuous(range = c(0.1, 10)) +
  labs(color = "Sub-Event Type", size = "Number of Events") +
  labs(title = "Violence targeting Civilians in Donetsk", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Conflict in Zaporizhia

During the initial stages of the invasion, Russian forces successfully occupied a significant portion of the Zaporizhia region. This included the entire coastline of the Sea of Azov, encompassing the Ukrainian navy base in Berdiansk, as well as an area extending from Kherson to the southern Donetsk regions, reaching the Dnipro river. The occupation also covered Melitopol, the region’s second-largest town. Ukrainian forces managed to halt the advancement of Russian forces in the Orikhiv and Huliaipole areas. While approximately half of the incidents targeting civilians in the Zaporizhia region involved shelling, air attacks, and drone strikes, civilians have also been directly targeted. These attacks include firing at vehicles carrying evacuating civilians, as well as instances of torture and execution. In areas under Russian occupation, there are frequent reports of the abduction of local officials, teachers, journalists, Ukrainian army veterans, and civil activists.

conflict_zaporizhia <- conflict %>%
  dplyr::filter(
                civilian_targeting != "",
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                admin1 == "Zaporizhia")
# Create a new column called 'new_event_type'
conflict_zaporizhia$new_event_type <- NA

# Map values based on 'sub_event_type'
conflict_zaporizhia$new_event_type[conflict_zaporizhia$sub_event_type %in% c("Attack", "Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")] <- conflict_zaporizhia$sub_event_type[conflict_zaporizhia$sub_event_type %in% c("Attack","Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")]
conflict_zaporizhia$new_event_type[!(conflict_zaporizhia$sub_event_type %in% c("Attack","Shelling/artillery/missile attack", "Air/drone strike", "Abduction/forced disappearance" , "Remote explosive/landmine/IED"))] <- "Other violence"
number_of_events_zaporizhia <- conflict_zaporizhia %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), new_event_type)
zaporizhia <- subset(ukraine_states_rds, NAME_1 == "Zaporizhzhya")
zaporizhia_map <- ggplot() +
  geom_polygon(data=zaporizhia,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
zaporizhia_map

zaporizhia_map +
  geom_point(data = number_of_events_zaporizhia, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
  geom_point(color="black", shape=21, data = number_of_events_zaporizhia, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
  scale_size_continuous(range = c(0.1, 10)) +
  labs(color = "Sub-Event Type", size = "Number of Events") +
  labs(title = "Violence targeting Civilians in Zaporizhia", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Explosive Threats for Civilians in Southern Ukraine

Russian attempts for landings from the Black Sea were unsuccessful. Russian forces invaded southern Ukraine from the annexed Crimean peninsula, successfully overtaking the Kherson region and its main city in March 2022. The Kherson and Mykolaiv regions experienced significant violence, with artillery strikes leading to high fatality numbers. The most common types of violence in Kherson were abductions, forced disappearances, torture, targeting primarily officials, journalists, activists, and those suspected of pro-Ukrainian views. In June 2022, Russian forces reportedly abducted about 50 Crimean Tatars from Kherson. Two significant incidents in the Odesa region include a missile strike that killed 8 and injured 10 civilians on April 2022, and an airstrike that killed at least 21 civilians on July 2022.

southern_ukraine_states_name = c("Mykolaiv", "Kherson", "Crimea", "Odesa" )
conflict_southern_ukraine <- conflict %>%
  dplyr::filter(
                civilian_targeting != "",
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                admin1 %in% southern_ukraine_states_name)
# Create a new column called 'new_event_type'
conflict_southern_ukraine$new_event_type <- NA

# Map values based on 'sub_event_type'
conflict_southern_ukraine$new_event_type[conflict_southern_ukraine$sub_event_type %in% c("Attack", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")] <- conflict_southern_ukraine$sub_event_type[conflict_southern_ukraine$sub_event_type %in% c("Attack", "Abduction/forced disappearance" , "Remote explosive/landmine/IED")]
conflict_southern_ukraine$new_event_type[!(conflict_southern_ukraine$sub_event_type %in% c("Attack", "Abduction/forced disappearance" , "Remote explosive/landmine/IED"))] <- "Other violence"
number_of_events_southern_ukraine <- conflict_southern_ukraine %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), new_event_type)
southern_ukraine <- subset(ukraine_states_rds, NAME_1 %in% southern_ukraine_states_rds_names)
southern_ukraine_map <- ggplot() +
  geom_polygon(data=southern_ukraine,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
southern_ukraine_map

southern_ukraine_map +
  geom_point(data = number_of_events_southern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, color=new_event_type)) +
  geom_point(color="black", shape=21, data = number_of_events_southern_ukraine, aes(x = longitude, y = latitude, size = number_of_events, fill=new_event_type)) +
  scale_size_continuous(range = c(0.1, 10)) +
  labs(color = "Sub-Event Type", size = "Number of Events") +
  labs(title = "Violence targeting Civilians in Southern Ukraine", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Constant Menace from the Skies in Central and Western Ukraine

Over 150 Russian missile, air, and drone strikes have targeted the Central and West regions, posing a significant threat to civilian safety. Approximately one-fifth of these strikes hit civilian areas, leading to over 80 fatalities. Two incidents accounted for most of the reported fatalities: a missile strike on a shopping mall, in Poltava, on June 2022, and a missile strike on a Vinnytsia concert hall on July 2022. At least 50 Russian strikes targeted energy infrastructure deep within Ukraine which caused power outages, with Vinnytsia being one of the most affected regions.

unique(conflict$admin1)
 [1] "Dnipropetrovsk"  "Luhansk"         "Donetsk"         "Kharkiv"         "Kherson"         "Sumy"            "Zaporizhia"     
 [8] "Kyiv City"       "Chernihiv"       "Crimea"          "Chernivtsi"      "Ivano-Frankivsk" "Khmelnytskyi"    "Lviv"           
[15] "Mykolaiv"        "Odesa"           "Poltava"         "Vinnytsia"       "Kirovograd"      "Zhytomyr"        "Ternopil"       
[22] "Cherkasy"        "Kyiv"            "Volyn"           NA                "Rivne"           "Zakarpattia"    
central_western_ukraine_states_name <-  c("Volyn", "Rivne", "Lviv", "Ternopil", "Khmelnytskyi", "Ivano-Frankivsk", "Zakarpattia", "Chernivtsi", "Vinnytsia", "Cherkasy", "Kirovograd", "Poltava" )

conflict_central_western_ukraine <- conflict %>%
  dplyr::filter(
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                sub_event_type == "Shelling/artillery/missile attack",
                admin1 %in% central_western_ukraine_states_name
                )
number_of_events_central_western_ukraine <- conflict_central_western_ukraine %>%
  group_by(latitude, longitude) %>%
  summarize(number_of_events = n(), .groups = "drop")
central_western_ukraine <- subset(ukraine_states_rds, NAME_1 %in% central_ukraine_states_rds_names | NAME_1 %in% western_ukraine_states_rds_names)
central_western_ukraine_map <- ggplot() +
  geom_polygon(data=central_western_ukraine,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
central_western_ukraine_map

central_western_ukraine_map +
  geom_point(color="black", shape=21, fill="darkblue", alpha=0.6, data = number_of_events_central_western_ukraine, aes(x = longitude, y = latitude, size = number_of_events)) +
  scale_size_continuous(range = c(1, 10), guide = 'legend', breaks = c(1, 10, 20, 50), labels = c("1", "10", "20", "50+")) +
  labs(size = "Number of Events") +
  labs(title = "Long-Range Strikes in Central and Western Ukraine", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

Interactive Map

library(leaflet)
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
ukraine_interactive_map <- leaflet() %>%
  addTiles() %>%
  setView(lng = 37.7933, lat = 48.1450, zoom = 7)
ukraine_interactive_map
eastern_ukraine_states_names = list("Dnipropetrovsk", "Luhansk", "Donetsk", "Kharkiv", "Zaporizhia")
conflict_eastern_ukraine <- conflict %>%
  dplyr::filter(
                event_date >= as.Date("2022-02-01") & event_date <= as.Date("2023-01-31"),
                event_type %in% c("Explosions/Remote violence", "Battles", "Violence against civilians"),
                admin1 %in% eastern_ukraine_states_names)
events <- data.frame(latitude = conflict_eastern_ukraine$latitude,
                     longitude = conflict_eastern_ukraine$longitude)
m <- ukraine_interactive_map %>%
  addCircleMarkers(data = events,
                   lng = ~longitude,
                   lat = ~latitude,
                   radius = 1,
                   color = "red",
                   fill = TRUE,
                   fillOpacity = 0.8)

# Display the map
m
m2 <- addPolygons(
  map = m,
  data = east_ukraine_states_rds,
  fillColor = "orange",
  fillOpacity = 0.2,
  color = "black",
  weight = 1
)
m2

Conclusion

The war in Ukraine has disrupted normal life and defied expectations of a quick subjugation. The aggressive actions of Russia have exposed millions of Ukrainians to violence and hardship. Mass graves indicate potential atrocities in areas under Russian occupation. Contamination of formerly occupied areas with mines poses a serious risk to returning civilians. The war has led to a contraction of Ukraine’s economy and internal and external displacement of millions. Remaining civilians face ongoing disruptions to utilities and constant threats of cross-border strikes and shelling. Ongoing occupation of a nuclear power plant by Russia, along with the threats of nuclear weapons, present continuous risks to the lives and environment of Ukraine and the surrounding region.

Pre-Invasion

The Euromaidan protests, which started in late 2013, were primarily centered in the capital city of Kyiv (Kiev) but spread to other regions as well. The protests involved clashes between demonstrators and law enforcement, resulting in instances of violence, injuries, and fatalities.

Before the Russian invasion the violence in eastern Ukraine was already concentrated in areas close to the Ukrainian-Russian border, particularly in the Donetsk and Luhansk regions. Cities such as Donetsk, Luhansk, Mariupol, and Sloviansk witnessed intense fighting and became hotspots of violence.

Both sides of the conflict engaged in military operations, including artillery shelling, sniper attacks, and armed clashes. The violence was not limited to specific cities but was spread across the conflict-affected regions.

The conflict resulted in a significant number of civilian casualties and widespread displacement of residents. Civilians, including those living in towns and villages near the front lines, faced the risk of violence and were often caught in the crossfire.

ukraine_map2

centroid <- ukraine_states_rds$centroid <- coordinates(ukraine_states_rds)
text <- geom_text(data = , aes(x = centroid[, 1], y = centroid[, 2], label = ukraine_states_rds$NAME_1), color = "black", size = 4)
pi_ukraine_map <- ukraine_map2 + 
  geom_text(aes(x = centroid[, 1], y = centroid[, 2], label = ukraine_states_rds_names), size=2) + labs(title = "Pre-Invasion Conflicts", fontface="bold") + theme_void() + theme(plot.title = element_text(hjust = 0.5, face = "bold")) +  coord_map(projection = "albers", lat0 = 49, lat1 = 54)
pi_ukraine_map

conflict_pi_ukraine <- conflict %>%
  dplyr::filter(
                event_date <= as.Date("2022-02-01"),
                 civilian_targeting != ""
                )
number_of_events_pi_ukraine <- conflict_pi_ukraine %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), event_type)
pi_ukraine_map +
  geom_point(data = number_of_events_pi_ukraine, aes(x = longitude, y = latitude, size = number_of_events, color=event_type)) +
  geom_point(color="black", shape=21, data = number_of_events_pi_ukraine, aes(x = longitude, y = latitude, size = number_of_events, fill=event_type)) +
  scale_size_continuous(range = c(0.1, 10)) +
  labs(color = "Event Type", size = "Number of Events") +
  labs(title = "Violence targeting Civilians in Pre-Invasion Ukraine", fontface="bold") + 
  labs(subtitle = "Before February 2022 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))
Coordinate system already present. Adding new coordinate system, which will replace the existing one.

Political Violence in Eastern Ukraine Pre-Invasion

conflict_eastern_ukraine_pi <- conflict %>%
  dplyr::filter(
                disorder_type == "Political violence",
                event_date < as.Date("2022-02-01"),
                event_type %in% c("Explosions/Remote violence", "Battles", "Violence against civilians"),
                admin1 %in% eastern_ukraine_states_names)
event_counts_eastern_ukraine_pi <- conflict_eastern_ukraine_pi %>%
  group_by(longitude, latitude) %>%
  reframe(number_of_events = n(), event_type)
eastern_ukraine_map <- ggplot() +
  geom_polygon(data=east_ukraine_states_rds,  aes(x = long, y = lat, group = group), fill="orange", alpha=0.2, color="black") + guides(fill = "none") + theme_void()
Regions defined for each Polygons
eastern_ukraine_map

centroid <- east_ukraine_states_rds$centroid <- coordinates(east_ukraine_states_rds)
centroid[2] = centroid[2]+0.4
centroid[7] = centroid[7]-0.4
centroid[3] = centroid[3]-0.4
text <- geom_text(data = , aes(x = centroid[, 1], y = centroid[, 2], label = c("Dnipropetrovsk", "Donetsk", "Kharkiv", "Luhansk", "Zaporizhia")), color = "black", size = 4)
eastern_ukraine_map +
  geom_point(data = event_counts_eastern_ukraine_pi, aes(x = longitude, y = latitude, size = number_of_events, color=event_type)) +
  geom_point(color="black", shape=21, data = event_counts_eastern_ukraine_pi, aes(x = longitude, y = latitude, size = number_of_events, fill=event_type)) +
  scale_size_continuous(range = c(0.1, 5)) +
  labs(color = "Event Type", size = "Number of Events") +
  labs(title = "Political Violence in Eastern Ukraine Pre-Invasion", fontface="bold") + 
  labs(subtitle = "February 2022 - January 2023 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5)) +
  text

conflict_ukraine_pi_riots <- conflict %>%
  dplyr::filter(
                disorder_type == "Political violence",
                event_date < as.Date("2022-02-01"),
                event_type == "Riots"
                )
ukraine_map2 +
  geom_point(color="black", shape=21, fill="orange", alpha=0.6, data = conflict_ukraine_pi_riots, aes(x = longitude, y = latitude, size = 1)) +
  labs(title = "Riots in Pre-Invasion Ukraine", fontface="bold") + 
  labs(subtitle = "Before February 2022 ") +
  coord_map(projection = "albers", lat0 = 49, lat1 = 54) +
  guides(size = "none") +
  theme_void() +
  theme(plot.title = element_text(hjust = 0.5, face="bold"), plot.subtitle = element_text(hjust = 0.5))

LS0tCmF1dGhvcjogIkVsaWYgw4dheXNhciwgR2lyYXkgQ2/Fn2t1biwgU3VkZSBCdWtldCBLaXByaSwgWmV5bmVwIEFrYW50Igp0aXRsZTogIkVjb24gNDk0IFNwYXRpYWwgRGF0YSBTY2llbmNlIFByb2plY3QgLSBBbmFseXNpcyBvZiBBQ0xFRCBSZXBvcnQgV2FyIGluIFVrcmFpbmUiCm91dHB1dDogaHRtbF9ub3RlYm9vawppbnN0aXR1dGU6ICJTYWJhbmNpIFVuaXZlcnNpdHkiCmZvcm1hdDoKICBwZGY6IGRlZmF1bHQKZWRpdG9yOiB2aXN1YWwKLS0tCgojIEVDT04gNDk0IC0gU3BhdGlhbCBEYXRhIFNjaWVuY2UgUHJvamVjdAoKT3VyIHByb2plY3QgYWltZWQgdG8gYW5hbHl6ZSB0aGUgVWtyYWluZSBjb25mbGljdCB1c2luZyBzcGF0aWFsIGFuYWx5c2lzIGFuZCBtYXBzIGdlbmVyYXRlZCB0aHJvdWdoIGRhdGEgZnJvbSBBQ0xFRCAoQXJtZWQgQ29uZmxpY3QgTG9jYXRpb24gJiBFdmVudCBEYXRhIFByb2plY3QpLiBGb2N1c2luZyBvbiB0aGUgdmlvbGVuY2UgdGFyZ2V0aW5nIGNpdmlsaWFucyBhZnRlciBpbnZhc2lvbiBvZiBSdXNzaWEgaW50byBVa3JhaW5lLCB3ZSB1dGlsaXplZCBSIHByb2dyYW1taW5nIHRvIGV4dHJhY3QgYW5kIHZpc3VhbGl6ZSB0aGUgY29uZmxpY3QgZGF0YSwgZW5hYmxpbmcgdXMgdG8gcHJlc2VudCBhIGNvbXByZWhlbnNpdmUgb3ZlcnZpZXcgb2YgdGhlIGV2ZW50cyBhbmQgdGhlaXIgc3BhdGlhbCBkaXN0cmlidXRpb24uCgpgYGB7cn0KbGlicmFyeShzcCkKbGlicmFyeShyYXN0ZXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoY29uZmxpY3RlZCkKYGBgCgojIyBJbnRyb2R1Y3Rpb24KCi0gICBSdXNzaWEgaW52YWRlZCBVa3JhaW5lIGluIEZlYnJ1YXJ5IDIwMjIsIHJlc3VsdGluZyBpbiB0aGUgaGlnaGVzdCBsZXZlbHMgb2YgcG9saXRpY2FsIHZpb2xlbmNlIHJlY29yZGVkIGluIGEgc2luZ2xlIGNvdW50cnkgYnkgQUNMRUQuCgotICAgQ2l2aWxpYW5zIGluIFVrcmFpbmUgaGF2ZSBmYWNlZCBzaGVsbGluZywgaW5kaXNjcmltaW5hdGUgc3RyaWtlcywgZGVsaWJlcmF0ZSBhdHRhY2tzLCBhbmQgaGFyc2ggdHJlYXRtZW50IGluIG9jY3VwaWVkIGFyZWFzLgoKLSAgIFJ1c3NpYW4gZm9yY2VzIHRhcmdldGVkIEt5aXYgYnV0IHJldHJlYXRlZCBpbiBub3J0aGVybiBVa3JhaW5lIHdoaWxlIHF1aWNrbHkgc2VpemluZyB0ZXJyaXRvcmllcyBpbiBzb3V0aGVybiBhbmQgZWFzdGVybiByZWdpb25zLgoKLSAgIE92ZXIgNSwwMDAgcmVwb3J0ZWQgY2l2aWxpYW4gZmF0YWxpdGllcyBoYXZlIG9jY3VycmVkLCBidXQgdGhlIGFjdHVhbCB0b2xsIGlzIGxpa2VseSBtdWNoIGhpZ2hlci4KCi0gICBEaWZmZXJlbnQgcmVnaW9ucyBvZiBVa3JhaW5lIGV4cGVyaWVuY2VkIHZhcnlpbmcgbGV2ZWxzIG9mIHZpb2xlbmNlIGFuZCBvY2N1cGF0aW9uIGR1cmluZyB0aGUgY29uZmxpY3QuCgpgYGB7cn0KI3VrcmFpbmVfc3RhdGVzX3JkcyA8LSByYXN0ZXI6OmdldERhdGEoJ0dBRE0nLCBjb3VudHJ5ID0gIlVLUiIsIGxldmVsID0gMSkKdWtyYWluZV9zdGF0ZXNfcmRzID0gcmVhZFJEUygidWtyYWluZS5yZHMiKSAjaHR0cHM6Ly9nYWRtLm9yZy9kb3dubG9hZF9jb3VudHJ5Lmh0bWwKYGBgCgpgYGB7cn0KdWtyYWluZV9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPXVrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IGlkKSwgZmlsbD0ib3JhbmdlIiwgYWxwaGEgPSAwLjYgKSArIGd1aWRlcyhmaWxsID0gIm5vbmUiKQp1a3JhaW5lX21hcApgYGAKCmBgYHtyfQplYXN0X3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyA8LSBsaXN0KCJEbmlwcm9wZXRyb3ZzJ2siLCAiRG9uZXRzJ2siLCAiTHVoYW5zJ2siICwgICJLaGFya2l2IiwgIlphcG9yaXpoemh5YSIpCgplYXN0X3VrcmFpbmVfc3RhdGVzX3JkcyA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgJWluJSBlYXN0X3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcykKYGBgCgpgYGB7cn0Kc291dGhfdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzIDwtIGxpc3QoIkNoZXJuaWhpdiIsICJLaWV2IiwgIktpZXYgQ2l0eSIsICJaaHl0b215ciIsICJTdW15IikKc291dGhfdWtyYWluZV9zdGF0ZXNfcmRzIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSAlaW4lIHNvdXRoX3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcykKYGBgCgpgYGB7cn0KY2VudHJhbF91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMgPC0gbGlzdCgiQ2hlcmthc3kiLCAiS2lyb3ZvaHJhZCIsICJQb2x0YXZhIiwgIlZpbm55dHN5YSIpCmNlbnRyYWxfdWtyYWluZV9zdGF0ZXNfcmRzIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSAlaW4lIGNlbnRyYWxfdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzKQpgYGAKCmBgYHtyfQp3ZXN0ZXJuX3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyA8LSBsaXN0KCJWb2x5biIsICJDaGVybml2dHNpIiwgIkl2YW5vLUZyYW5raXZzJ2siLCAiS2htZWwnbnl0cydreXkiLCAiUml2bmUiLCAiTCd2aXYiLCAiVGVybm9waWwnIiwgIlRyYW5zY2FycGF0aGlhIikKd2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHMgPC0gc3Vic2V0KHVrcmFpbmVfc3RhdGVzX3JkcywgTkFNRV8xICVpbiUgd2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCmBgYAoKYGBge3J9CnNvdXRoZXJuX3VrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyA8LSBsaXN0KCJDcmltZWEiLCAiS2hlcnNvbiIsICAiTXlrb2xheWl2IiwgIk9kZXNzYSIpCnNvdXRoZXJuX3VrcmFpbmVfc3RhdGVzX3JkcyA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgJWluJSBzb3V0aGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCmBgYAoKYGBge3J9CnVrcmFpbmVfbWFwMiA8LSB1a3JhaW5lX21hcCArIAogIGdlb21fcG9seWdvbihkYXRhPWVhc3RfdWtyYWluZV9zdGF0ZXNfcmRzLCAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgZmlsbD0icmVkIiwgYWxwaGE9MC4yLCBjb2xvcj0iYmxhY2siKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9c291dGhfdWtyYWluZV9zdGF0ZXNfcmRzLCAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgZmlsbD0iYmxhY2siLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1jZW50cmFsX3VrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9ImRhcmtibHVlIiwgYWxwaGE9MC40LCBjb2xvcj0iYmxhY2siKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9d2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHMsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJsaWdodGJsdWUiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1zb3V0aGVybl91a3JhaW5lX3N0YXRlc19yZHMsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpCgp1a3JhaW5lX21hcDIKYGBgCgpgYGB7cn0KY2VudHJvaWQgPC0gdWtyYWluZV9zdGF0ZXNfcmRzJGNlbnRyb2lkIDwtIGNvb3JkaW5hdGVzKHVrcmFpbmVfc3RhdGVzX3JkcykKdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzIDwtIHVrcmFpbmVfc3RhdGVzX3JkcyROQU1FXzEKYGBgCgpgYGB7cn0KdWtyYWluZV9tYXAzIDwtIHVrcmFpbmVfbWFwMiArIAogIGdlb21fdGV4dChhZXMoeCA9IGNlbnRyb2lkWywgMV0sIHkgPSBjZW50cm9pZFssIDJdLCBsYWJlbCA9IHVrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyksIHNpemU9MikgKyBsYWJzKHRpdGxlID0gIlJlZ2lvbnMgb2YgVWtyYWluZSIsIGZvbnRmYWNlPSJib2xkIikgKyB0aGVtZV92b2lkKCkgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSkgKyAgY29vcmRfbWFwKHByb2plY3Rpb24gPSAiYWxiZXJzIiwgbGF0MCA9IDQ5LCBsYXQxID0gNTQpCnVrcmFpbmVfbWFwMwpgYGAKCiMjIENvbmZsaWN0IERhdGEgKEFDTEVEKQoKYGBge3J9CmVhc3Rlcm5fdWtyYWluZV9zdGF0ZXNfbmFtZXMgPSBsaXN0KCJEbmlwcm9wZXRyb3ZzayIsICJMdWhhbnNrIiwgIkRvbmV0c2siLCAiS2hhcmtpdiIsICJaYXBvcml6aGlhIikKYGBgCgpgYGB7cn0KY29uZmxpY3QgPC0gcmVhZF9jc3YoJ3VrcmFpbmUuY3N2Jywgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkKY29uZmxpY3QkZXZlbnRfZGF0ZSA8LSBhcy5EYXRlKGNvbmZsaWN0JGV2ZW50X2RhdGUsIGZvcm1hdCA9ICIlZCAlQiAlWSIpCmBgYAoKYGBge3J9CnVuaXF1ZShjb25mbGljdCRhZG1pbjEpCmBgYAoKYGBge3J9CnVuaXF1ZShjb25mbGljdCRldmVudF90eXBlKQpgYGAKCmBgYHtyfQp1bmlxdWUoY29uZmxpY3Qkc3ViX2V2ZW50X3R5cGUpCmBgYAoKIyMgQXBwYXJlbnQgV2FyIENyaW1lcyBpbiBOb3J0aGVybiBVa3JhaW5lCgpJbiBub3J0aGVybiBVa3JhaW5lLCBBQ0xFRCByZWNvcmRzIG92ZXIgNDAwIGluY2lkZW50cyB0YXJnZXRpbmcgY2l2aWxpYW5zLCB3aXRoIGEgc2lnbmlmaWNhbnQgbnVtYmVyIG9jY3VycmluZyBkdXJpbmcgdGhlIFJ1c3NpYW4gYWR2YW5jZSBhbmQgc3Vic2VxdWVudCBvY2N1cGF0aW9uLiBTaGVsbGluZywgYXJ0aWxsZXJ5LCBhbmQgbWlzc2lsZSBhdHRhY2tzIHdlcmUgdGhlIG1vc3QgY29tbW9uIHR5cGVzIG9mIHZpb2xlbmNlLCBidXQgZGlyZWN0IGF0dGFja3Mgb24gY2l2aWxpYW4gcG9wdWxhdGlvbnMgcmVzdWx0ZWQgaW4gdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHJlcG9ydGVkIGNpdmlsaWFuIGZhdGFsaXRpZXMuIE1hc3MgZ3JhdmVzIHdlcmUgZGlzY292ZXJlZCBmb2xsb3dpbmcgdGhlIFJ1c3NpYW4gcmV0cmVhdC4gVGhlIEt5aXYgcmVnaW9uLCBpbmNsdWRpbmcgdGhlIGNpdHkgb2YgS3lpdiwgd2FzIG1vc3QgYWZmZWN0ZWQgYnkgdGhlc2Ugc3RyaWtlcywgd2hpbGUgdGhlIFN1bXkgcmVnaW9uIGNvbnRpbnVlZCB0byBzdWZmZXIgZnJvbSBzdHJpa2VzIGFsb25nIGl0cyBib3JkZXIgYXJlYXMgd2l0aCBSdXNzaWEgdGhyb3VnaG91dCB0aGUgeWVhci4KSW5jaWRlbnRzIHJlbGF0ZWQgdG8gYWNjaWRlbnRhbCBkZXRvbmF0aW9uIG9mIG1pbmVzIGFuZCBleHBsb3NpdmVzIGNvbnRpbnVlZCB0byBvY2N1ciBkdXJpbmcgYW5kIGFmdGVyIHRoZSBpbnZhc2lvbi4gQUNMRUQgcmVjb3JkcyBhdCBsZWFzdCA0MyBzdWNoIGV2ZW50cyByZXN1bHRpbmcgaW4gYXQgbGVhc3QgMzQgcmVwb3J0ZWQgZmF0YWxpdGllcywgd2l0aCB0aGUgaGlnaGVzdCBpbmNpZGVuY2UgaW4gQXByaWwgYW5kIE1heSAyMDIyIGluIHRoZSBLeWl2IGFuZCBDaGVybmloaXYgcmVnaW9ucyBmb2xsb3dpbmcgdGhlIFJ1c3NpYW4gd2l0aGRyYXdhbC4KCmBgYHtyfQpmaWx0ZXJlZF9kYXRhIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGNpdmlsaWFuX3RhcmdldGluZyE9IiIpCmBgYAoKYGBge3J9CmZpbHRlcmVkX2RhdGEgPC0gZmlsdGVyZWRfZGF0YVtmaWx0ZXJlZF9kYXRhJGFkbWluMSAlaW4lIGMoIlpoeXRvbXlyIiwgIkt5aXYgQ2l0eSIsICJLeWl2IiwgIlN1bXkiLCAiQ2hlcm5paGl2IiksXQpmaWx0ZXJlZF9kYXRhJG1vbnRoX3llYXIgPC0gZm9ybWF0KGZpbHRlcmVkX2RhdGEkZXZlbnRfZGF0ZSwgIiVCLSVZIikKYGBgCgpgYGB7cn0KZWFzdGVybiA8LSBmaWx0ZXJlZF9kYXRhW2ZpbHRlcmVkX2RhdGEkYWRtaW4xICVpbiUgYygiRG5pcHJvcGV0cm92c2siLCAiRG9uZXRzayIsICJLaGFya2l2IiwgIkx1aGFuc2siLCAiWmFwb3JpemhpYSIpLF0KZWFzdGVybiRtb250aF95ZWFyIDwtIGZvcm1hdChlYXN0ZXJuJGV2ZW50X2RhdGUsICIlQi0lWSIpCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBjYWxsZWQgJ25ld19ldmVudF90eXBlJwpmaWx0ZXJlZF9kYXRhJG5ld19ldmVudF90eXBlIDwtIE5BCgojIE1hcCB2YWx1ZXMgYmFzZWQgb24gJ3N1Yl9ldmVudF90eXBlJwpmaWx0ZXJlZF9kYXRhJG5ld19ldmVudF90eXBlW2ZpbHRlcmVkX2RhdGEkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIsICJBdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siKV0gPC0gZmlsdGVyZWRfZGF0YSRzdWJfZXZlbnRfdHlwZVtmaWx0ZXJlZF9kYXRhJHN1Yl9ldmVudF90eXBlICVpbiUgYygiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIildCmZpbHRlcmVkX2RhdGEkbmV3X2V2ZW50X3R5cGVbIShmaWx0ZXJlZF9kYXRhJHN1Yl9ldmVudF90eXBlICVpbiUgYygiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIikpXSA8LSAiT3RoZXIgdmlvbGVuY2UiCmBgYAoKYGBge3J9CmdncGxvdChmaWx0ZXJlZF9kYXRhLCBhZXMoeCA9IG1vbnRoX3llYXIsIGZpbGwgPSBuZXdfZXZlbnRfdHlwZSwgKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIikgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJOdW1iZXIgb2YgRXZlbnRzIiwgdGl0bGUgPSAiVmlvbGVuY2UgVGFyZ2V0aW5nIENpdmlsaWFucyBpbiBOb3J0aGVybiBVa3JhaW5lIiwKICAgICAgIHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMiLAogICAgICAgZmlsbCA9ICJTdWItRXZlbnQgVHlwZSIpICsKICB0aGVtZV9idygpCmBgYApgYGB7cn0KIyBDb252ZXJ0IG1vbnRoX3llYXIgY29sdW1uIHRvIHByb3BlciBkYXRlIGZvcm1hdApmaWx0ZXJlZF9kYXRhJG1vbnRoX3llYXIgPC0gYXMuRGF0ZShwYXN0ZTAoIjAxLSIsIGZpbHRlcmVkX2RhdGEkbW9udGhfeWVhciksIGZvcm1hdCA9ICIlZC0lQi0lWSIpCgojIFNvcnQgdGhlIGRhdGEgYnkgdGhlIG1vbnRoX3llYXIgY29sdW1uCmZpbHRlcmVkX2RhdGEgPC0gZmlsdGVyZWRfZGF0YVtvcmRlcihmaWx0ZXJlZF9kYXRhJG1vbnRoX3llYXIpLCBdCgoKIyBDcmVhdGUgdGhlIGJhciBjaGFydApnZ3Bsb3QoZmlsdGVyZWRfZGF0YSwgYWVzKHggPSBtb250aF95ZWFyLCBmaWxsID0gbmV3X2V2ZW50X3R5cGUsICkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIpICsKICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiTnVtYmVyIG9mIEV2ZW50cyIsIHRpdGxlID0gIlZpb2xlbmNlIFRhcmdldGluZyBDaXZpbGlhbnMgaW4gTm9ydGhlcm4gVWtyYWluZSIsCiAgICAgICBzdWJ0aXRsZSA9ICJGZWJydWFyeSAyMDIyIC0gSmFudWFyeSAyMDIzIiwKICAgICAgIGZpbGwgPSAiU3ViLUV2ZW50IFR5cGUiKSArCiAgdGhlbWVfYncoKQoKYGBgCgpgYGB7cn0KCiMgQ29udmVydCBtb250aF95ZWFyIGNvbHVtbiB0byBwcm9wZXIgZGF0ZSBmb3JtYXQKZWFzdGVybiRtb250aF95ZWFyIDwtIGFzLkRhdGUocGFzdGUwKCIwMS0iLCBlYXN0ZXJuJG1vbnRoX3llYXIpLCBmb3JtYXQgPSAiJWQtJUItJVkiKQoKIyBTb3J0IHRoZSBkYXRhIGJ5IHRoZSBtb250aF95ZWFyIGNvbHVtbgplYXN0ZXJuIDwtIGVhc3Rlcm5bb3JkZXIoZWFzdGVybiRtb250aF95ZWFyKSwgXQoKCiMgQ3JlYXRlIHRoZSBiYXIgY2hhcnQKZ2dwbG90KGVhc3Rlcm4sIGFlcyh4ID0gbW9udGhfeWVhciwgZmlsbCA9IGFkbWluMSwgKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIikgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJOdW1iZXIgb2YgRXZlbnRzIiwgdGl0bGUgPSAiVmlvbGVuY2UgVGFyZ2V0aW5nIENpdmlsaWFucyBpbiBFYXN0ZXJuIFVrcmFpbmUiLAogICAgICAgc3VidGl0bGUgPSAiRmVicnVhcnkgMjAyMiAtIEphbnVhcnkgMjAyMyIsCiAgICAgICBmaWxsID0gIlJlZ2lvbiIpICsKICB0aGVtZV9idygpCmBgYAoKCiMjIEhlYXZ5IEZpZ2h0aW5nIEFsb25nIHRoZSBGcm9udGxpbmUgaW4gRWFzdGVybiBVa3JhaW5lCgpFYXN0ZXJuIFVrcmFpbmUgZmFjZXMgdW5wcmVjZWRlbnRlZCB2aW9sZW5jZSwgd2l0aCB0aHJlZS1xdWFydGVycyBvZiBwb2xpdGljYWwgdmlvbGVuY2UgZXZlbnRzIG9jY3VycmluZyBpbiB0aGUgcmVnaW9uLCBwcmltYXJpbHkgZHVlIHRvIHNoZWxsaW5nLCBhcnRpbGxlcnksIGFuZCBtaXNzaWxlIGF0dGFja3MuIERlc3BpdGUgcmVsYXRpdmUgZGlzdGFuY2UgZnJvbSB0aGUgZnJvbnRsaW5lLCB0aGUgRG5pcHJvcGV0cm92c2sgcmVnaW9uIHJlbWFpbnMgYXQgcmlzaywgYXMgUnVzc2lhIGNvbnRpbnVlcyBhaXIgYW5kIG1pc3NpbGUgc3RyaWtlcywgZXhlbXBsaWZpZWQgYnkgdGhlIGRlYWRseSBpbmNpZGVudCBpbiBEbmlwcm8gb24gMTQgSmFudWFyeSAyMDIzLgoKIyMjIFBvbGl0aWNhbCBWaW9sZW5jZSBpbiBFYXN0ZXJuIFVrcmFpbmUKCkVhc3Rlcm4gcGFydHMgb2YgZWFzdGVybiBVa3JhaW5lIGhhcyBiZWVuIGhpZ2hseSBjb250ZXN0ZWQgc2luY2UgdGhlIGJlZ2lubmluZyBvZiB0aGUgaW52YXNpb24uIFRoZSBlYXN0ZXJuIHBvcnRpb24gb2YgdGhlIEtoYXJraXYgcmVnaW9uLCB3aGljaCB3YXMgb2NjdXBpZWQgYnkgUnVzc2lhbiBmb3JjZXMsIHNlcnZlZCBhcyBhIGJhc2UgZm9yIHRoZWlyIG9mZmVuc2l2ZXMgaW4gdGhlIEx1aGFuc2sgYW5kIERvbmV0c2sgcmVnaW9ucy4gVGhlIEx1aGFuc2sgcmVnaW9uIGV4cGVyaWVuY2VkIGludGVuc2UgdmlvbGVuY2UgYmV0d2VlbiBsYXRlIEZlYnJ1YXJ5IGFuZCBtaWQtc3VtbWVyIDIwMjIsIGFzIFJ1c3NpYW4gZm9yY2VzIGNhcHR1cmVkIHRvd25zIGJ5IGRlc3Ryb3lpbmcgdGhlbSB3aXRoIGFydGlsbGVyeS4gQSBzaW1pbGFyIGFwcHJvYWNoIHdhcyBlbXBsb3llZCBpbiB0aGUgc3ByaW5nIG9mIDIwMjIgdG8gY2FwdHVyZSBNYXJpdXBvbCwgdGhlIGxhc3QgVWtyYWluaWFuIHN0cm9uZ2hvbGQgaW4gdGhlIHNvdXRoZXJuIERvbmV0c2sgcmVnaW9uLCByZXN1bHRpbmcgaW4gZGlyZSBjb25zZXF1ZW5jZXMgZm9yIGJvdGggdHJhcHBlZCBVa3JhaW5pYW4gbWlsaXRhcnkgcGVyc29ubmVsIGFuZCBjaXZpbGlhbnMuIFRoZSBaYXBvcml6aGlhIHJlZ2lvbiBleHBlcmllbmNlZCByZWxhdGl2ZWx5IGxvd2VyIGxldmVscyBvZiBhcm1lZCB2aW9sZW5jZSBkdWUgdG8gUnVzc2lhJ3Mgc3dpZnQgb2NjdXBhdGlvbiBpbiBsYXRlIEZlYnJ1YXJ5IGFuZCBlYXJseSBNYXJjaCAyMDIyLgoKCmBgYHtyfQpjb25mbGljdF9lYXN0ZXJuX3VrcmFpbmUgPC0gY29uZmxpY3QgJT4lCiAgZHBseXI6OmZpbHRlcigKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPj0gYXMuRGF0ZSgiMjAyMi0wMi0wMSIpICYgZXZlbnRfZGF0ZSA8PSBhcy5EYXRlKCIyMDIzLTAxLTMxIiksCiAgICAgICAgICAgICAgICBldmVudF90eXBlICVpbiUgYygiRXhwbG9zaW9ucy9SZW1vdGUgdmlvbGVuY2UiLCAiQmF0dGxlcyIsICJWaW9sZW5jZSBhZ2FpbnN0IGNpdmlsaWFucyIpLAogICAgICAgICAgICAgICAgYWRtaW4xICVpbiUgZWFzdGVybl91a3JhaW5lX3N0YXRlc19uYW1lcykKYGBgCgpgYGB7cn0KZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZSA8LSBjb25mbGljdF9lYXN0ZXJuX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBldmVudF90eXBlKQpgYGAKCmBgYHtyfQplYXN0X3VrcmFpbmVfc3RhdGVzX3JkcwpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwIDwtIGdncGxvdCgpICsKICBnZW9tX3BvbHlnb24oZGF0YT1lYXN0X3VrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9Im9yYW5nZSIsIGFscGhhPTAuMiwgY29sb3I9ImJsYWNrIikgKyBndWlkZXMoZmlsbCA9ICJub25lIikgKyB0aGVtZV92b2lkKCkKZWFzdGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjZW50cm9pZCA8LSBlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcyRjZW50cm9pZCA8LSBjb29yZGluYXRlcyhlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcykKY2VudHJvaWRbMl0gPSBjZW50cm9pZFsyXSswLjQKY2VudHJvaWRbN10gPSBjZW50cm9pZFs3XS0wLjQKY2VudHJvaWRbM10gPSBjZW50cm9pZFszXS0wLjQKdGV4dCA8LSBnZW9tX3RleHQoZGF0YSA9ICwgYWVzKHggPSBjZW50cm9pZFssIDFdLCB5ID0gY2VudHJvaWRbLCAyXSwgbGFiZWwgPSBjKCJEbmlwcm9wZXRyb3ZzayIsICJEb25ldHNrIiwgIktoYXJraXYiLCAiTHVoYW5zayIsICJaYXBvcml6aGlhIikpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA0KQpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBldmVudF9jb3VudHNfZWFzdGVybl91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9ZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGZpbGw9ZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgNSkpICsKICBsYWJzKGNvbG9yID0gIkV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJQb2xpdGljYWwgVmlvbGVuY2UgaW4gRWFzdGVybiBVa3JhaW5lIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiRmVicnVhcnkgMjAyMiAtIEphbnVhcnkgMjAyMyAiKSArCiAgY29vcmRfbWFwKHByb2plY3Rpb24gPSAiYWxiZXJzIiwgbGF0MCA9IDQ5LCBsYXQxID0gNTQpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsKICB0ZXh0CmBgYAoKIyMjIENvbmZsaWN0IGluIEtoYXJraXYKCkRlc3BpdGUgZmFpbGluZyB0byBicmVhayBVa3JhaW5pYW4gZGVmZW5zZXMgaW4gYW5kIGFyb3VuZCBLaGFya2l2IGNpdHksIFJ1c3NpYW4gZm9yY2VzIGhhZCB0YWtlbiBjb250cm9sIG9mIHRoZSBtYWpvcml0eSBvZiB0aGUgbm9ydGhlcm4gYW5kIGVhc3Rlcm4gcGFydHMgb2YgdGhlIHJlZ2lvbiBieSBBcHJpbCAyMDIyLCBpbmNsdWRpbmcgdGhlIHN0cmF0ZWdpY2FsbHkgaW1wb3J0YW50IHRyYW5zcG9ydCBodWIgb2YgSXppdW0uIEhvd2V2ZXIsIFVrcmFpbmUgbWFuYWdlZCB0byBsaWJlcmF0ZSBhbG1vc3QgdGhlIGVudGlyZSByZWdpb24gaW4gYW4gdW5leHBlY3RlZCBjb3VudGVyLW9mZmVuc2l2ZSBpbiBTZXB0ZW1iZXIgMjAyMi4gQW1vbmcgdGhlIG1vcmUgdGhhbiA4MDAgaW5jaWRlbnRzIHRhcmdldGluZyBjaXZpbGlhbnMsIGFwcHJveGltYXRlbHkgdGhyZWUtcXVhcnRlcnMgaW52b2x2ZWQgYXJ0aWxsZXJ5LCBtaXNzaWxlcywgYW5kIGFpcnN0cmlrZXMsIHdoaWNoIGFsc28gYWNjb3VudGVkIGZvciB0aGUgbWFqb3JpdHkgb2YgcmVwb3J0ZWQgY2l2aWxpYW4gZGVhdGhzIGluIHRoZSByZWdpb24uIEFyb3VuZCBvbmUtdGhpcmQgb2YgdGhlc2UgaW5jaWRlbnRzIG9jY3VycmVkIGluIE1hcmNoIDIwMjIgYWxvbmUuCgpgYGB7cn0KY29uZmxpY3Rfa2hhcmtpdiA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgY2l2aWxpYW5fdGFyZ2V0aW5nICE9ICIiLAogICAgICAgICAgICAgICAgZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGFkbWluMSA9PSAiS2hhcmtpdiIpCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBjYWxsZWQgJ25ld19ldmVudF90eXBlJwpjb25mbGljdF9raGFya2l2JG5ld19ldmVudF90eXBlIDwtIE5BCgojIE1hcCB2YWx1ZXMgYmFzZWQgb24gJ3N1Yl9ldmVudF90eXBlJwpjb25mbGljdF9raGFya2l2JG5ld19ldmVudF90eXBlW2NvbmZsaWN0X2toYXJraXYkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIsICJBdHRhY2siKV0gPC0gY29uZmxpY3Rfa2hhcmtpdiRzdWJfZXZlbnRfdHlwZVtjb25mbGljdF9raGFya2l2JHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIildCmNvbmZsaWN0X2toYXJraXYkbmV3X2V2ZW50X3R5cGVbIShjb25mbGljdF9raGFya2l2JHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiLCAiQXR0YWNrIikpXSA8LSAiT3RoZXIgdmlvbGVuY2UiCmBgYAoKYGBge3J9Cm51bWJlcl9vZl9ldmVudHNfa2hhcmtpdiA8LSBjb25mbGljdF9raGFya2l2ICU+JQogIGdyb3VwX2J5KGxvbmdpdHVkZSwgbGF0aXR1ZGUpICU+JQogIHJlZnJhbWUobnVtYmVyX29mX2V2ZW50cyA9IG4oKSwgbmV3X2V2ZW50X3R5cGUpCmBgYAoKYGBge3J9CmtoYXJraXYgPC0gc3Vic2V0KHVrcmFpbmVfc3RhdGVzX3JkcywgTkFNRV8xID09ICJLaGFya2l2IikKa2hhcmtpdl9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPWtoYXJraXYsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCmtoYXJraXZfbWFwCmBgYAoKYGBge3J9CmtoYXJraXZfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX2toYXJraXYsIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBjb2xvcj1uZXdfZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19raGFya2l2LCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1uZXdfZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgMTApKSArCiAgbGFicyhjb2xvciA9ICJTdWItRXZlbnQgVHlwZSIsIHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIlZpb2xlbmNlIHRhcmdldGluZyBDaXZpbGlhbnMgaW4gS2hhcmtpdiIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyMgQ29uZmxpY3QgaW4gTHVoYW5zawoKVGhlIGV4dGVuc2l2ZSB1c2Ugb2YgYXJ0aWxsZXJ5LCBtaXNzaWxlcywgYW5kIGFpcnN0cmlrZXMsIGFsb25nIHdpdGggaW50ZW5zZSBjbG9zZSBjb21iYXQsIHJlc3VsdGVkIGluIHNpZ25pZmljYW50IHN1ZmZlcmluZyBmb3IgdGhlIGNpdmlsaWFuIHBvcHVsYXRpb24gaW4gdGhlIEx1aGFuc2sgcmVnaW9uLiBUcmFnaWMgaW5jaWRlbnRzIG9jY3VycmVkLCBzdWNoIGFzIHRoZSBzaGVsbGluZyBvZiBhIG51cnNpbmcgaG9tZSBpbiBLcmVtaW5uYSBvbiBNYXJjaCAxMSwgMjAyMiwgd2hpY2ggcmVwb3J0ZWRseSBsZWQgdG8gdGhlIGRlYXRoIG9mIDU2IGVsZGVybHkgcGF0aWVudHMuIEFkZGl0aW9uYWxseSwgYW4gYWlyc3RyaWtlIG9uIGEgc2Nob29sIHVzZWQgYXMgYSBzaGVsdGVyIGluIEJpbG9ob3JpdmthIG9uIE1heSA3LCAyMDIyLCByZXN1bHRlZCBpbiB0aGUgbG9zcyBvZiBhdCBsZWFzdCA2MCBsaXZlcy4gVGhlIHNoZWxsaW5nIG9mIFNldmVyb2RvbmV0c2sgaW4gTWFyY2ggYW5kIE1heSAyMDIyIGFsc28gY2xhaW1lZCB0aGUgbGl2ZXMgb2Ygb3ZlciA1MCBjaXZpbGlhbnMuIEFmdGVyIHRoZSBSdXNzaWFuIG9jY3VwYXRpb24gb2YgdGhlIHJlZ2lvbiBpbiB0aGUgc3VtbWVyIG9mIDIwMjIsIHRoZXJlIHdhcyBhIHNpZ25pZmljYW50IGRlY3JlYXNlIGluIHJlcG9ydHMgb2YgY2l2aWxpYW5zIGJlaW5nIHRhcmdldGVkLCBhbHRob3VnaCB0aGUgcmVnaW9uIGhhcyByZW1haW5lZCBoaWdobHkgdm9sYXRpbGUsIHBhcnRpY3VsYXJseSBzaW5jZSBhdXR1bW4uIAoKYGBge3J9CmNvbmZsaWN0X2x1aGFuc2sgPC0gY29uZmxpY3QgJT4lCiAgZHBseXI6OmZpbHRlcigKICAgICAgICAgICAgICAgIGNpdmlsaWFuX3RhcmdldGluZyAhPSAiIiwKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPj0gYXMuRGF0ZSgiMjAyMi0wMi0wMSIpICYgZXZlbnRfZGF0ZSA8PSBhcy5EYXRlKCIyMDIzLTAxLTMxIiksCiAgICAgICAgICAgICAgICBhZG1pbjEgPT0gIkx1aGFuc2siKQpgYGAKCmBgYHtyfQojIENyZWF0ZSBhIG5ldyBjb2x1bW4gY2FsbGVkICduZXdfZXZlbnRfdHlwZScKY29uZmxpY3RfbHVoYW5zayRuZXdfZXZlbnRfdHlwZSA8LSBOQQoKIyBNYXAgdmFsdWVzIGJhc2VkIG9uICdzdWJfZXZlbnRfdHlwZScKY29uZmxpY3RfbHVoYW5zayRuZXdfZXZlbnRfdHlwZVtjb25mbGljdF9sdWhhbnNrJHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJBdHRhY2siKV0gPC0gY29uZmxpY3RfbHVoYW5zayRzdWJfZXZlbnRfdHlwZVtjb25mbGljdF9sdWhhbnNrJHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJBdHRhY2siKV0KY29uZmxpY3RfbHVoYW5zayRuZXdfZXZlbnRfdHlwZVshKGNvbmZsaWN0X2x1aGFuc2skc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIkF0dGFjayIpKV0gPC0gIk90aGVyIHZpb2xlbmNlIgpgYGAKCmBgYHtyfQpudW1iZXJfb2ZfZXZlbnRzX2x1aGFuc2sgPC0gY29uZmxpY3RfbHVoYW5zayAlPiUKICBncm91cF9ieShsb25naXR1ZGUsIGxhdGl0dWRlKSAlPiUKICByZWZyYW1lKG51bWJlcl9vZl9ldmVudHMgPSBuKCksIG5ld19ldmVudF90eXBlKQpgYGAKCmBgYHtyfQpsdWhhbnNrIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSA9PSAiTHVoYW5zJ2siKQpsdWhhbnNrX21hcCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9bHVoYW5zaywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9Im9yYW5nZSIsIGFscGhhPTAuMiwgY29sb3I9ImJsYWNrIikgKyBndWlkZXMoZmlsbCA9ICJub25lIikgKyB0aGVtZV92b2lkKCkKbHVoYW5za19tYXAKYGBgCgpgYGB7cn0KbHVoYW5za19tYXAgKwogIGdlb21fcG9pbnQoZGF0YSA9IG51bWJlcl9vZl9ldmVudHNfbHVoYW5zaywgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGNvbG9yPW5ld19ldmVudF90eXBlKSkgKwogIGdlb21fcG9pbnQoY29sb3I9ImJsYWNrIiwgc2hhcGU9MjEsIGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX2x1aGFuc2ssIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBmaWxsPW5ld19ldmVudF90eXBlKSkgKwogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMC4xLCAxMCkpICsKICBsYWJzKGNvbG9yID0gIlN1Yi1FdmVudCBUeXBlIiwgc2l6ZSA9ICJOdW1iZXIgb2YgRXZlbnRzIikgKwogIGxhYnModGl0bGUgPSAiVmlvbGVuY2UgdGFyZ2V0aW5nIENpdmlsaWFucyBpbiBMdWhhbnNrIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiRmVicnVhcnkgMjAyMiAtIEphbnVhcnkgMjAyMyAiKSArCiAgY29vcmRfbWFwKHByb2plY3Rpb24gPSAiYWxiZXJzIiwgbGF0MCA9IDQ5LCBsYXQxID0gNTQpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlPSJib2xkIiksIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCiMjIyBDb25mbGljdCBpbiBEb25ldHNrCgpBQ0xFRCBkYXRhIGRvY3VtZW50cyBtb3JlIHRoYW4gMTYsMDAwIGluY2lkZW50cyBpbiB0aGUgRG9uZXRzayByZWdpb24sIHdpdGggb3ZlciAxMiwwMDAgb2YgdGhlbSBpbnZvbHZpbmcgc2hlbGxpbmcsIGFydGlsbGVyeSwgbWlzc2lsZXMsIGFuZCBhaXJzdHJpa2VzLiBPbmx5IGEgcmVsYXRpdmVseSBzbWFsbCBudW1iZXIgb2YgdGhlc2UgaW5jaWRlbnRzLCBhcm91bmQgODAwLCBzcGVjaWZpY2FsbHkgdGFyZ2V0ZWQgY2l2aWxpYW5zLiBQcmlvciB0byB0aGUgUnVzc2lhbiBvY2N1cGF0aW9uLCB0aGUgY2l0eSBvZiBNYXJpdXBvbCB3aXRuZXNzZWQgbXVsdGlwbGUgaW5jaWRlbnRzIHJlc3VsdGluZyBpbiBzaWduaWZpY2FudCBjYXN1YWx0aWVzLiBNYXNzIGNhc3VhbHR5IGV2ZW50cyBjYXVzZWQgYnkgbG9uZy1yYW5nZSBtaXNzaWxlIGFuZCBhcnRpbGxlcnkgc3RyaWtlcyB3ZXJlIHJlcG9ydGVkIGluIHZhcmlvdXMgYXJlYXMgb2YgdGhlIHJlZ2lvbiwgYWZmZWN0aW5nIGJvdGggc2lkZXMgb2YgdGhlIGxpbmUgb2YgY29udGFjdC4KCmBgYHtyfQpjb25mbGljdF9kb25ldHNrIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoCiAgICAgICAgICAgICAgICBjaXZpbGlhbl90YXJnZXRpbmcgIT0gIiIsCiAgICAgICAgICAgICAgICBldmVudF9kYXRlID49IGFzLkRhdGUoIjIwMjItMDItMDEiKSAmIGV2ZW50X2RhdGUgPD0gYXMuRGF0ZSgiMjAyMy0wMS0zMSIpLAogICAgICAgICAgICAgICAgYWRtaW4xID09ICJEb25ldHNrIikKYGBgCgpgYGB7cn0KIyBDcmVhdGUgYSBuZXcgY29sdW1uIGNhbGxlZCAnbmV3X2V2ZW50X3R5cGUnCmNvbmZsaWN0X2RvbmV0c2skbmV3X2V2ZW50X3R5cGUgPC0gTkEKCiMgTWFwIHZhbHVlcyBiYXNlZCBvbiAnc3ViX2V2ZW50X3R5cGUnCmNvbmZsaWN0X2RvbmV0c2skbmV3X2V2ZW50X3R5cGVbY29uZmxpY3RfZG9uZXRzayRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIlNoZWxsaW5nL2FydGlsbGVyeS9taXNzaWxlIGF0dGFjayIsICJBaXIvZHJvbmUgc3RyaWtlIiwgIkFiZHVjdGlvbi9mb3JjZWQgZGlzYXBwZWFyYW5jZSIgLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiKV0gPC0gY29uZmxpY3RfZG9uZXRzayRzdWJfZXZlbnRfdHlwZVtjb25mbGljdF9kb25ldHNrJHN1Yl9ldmVudF90eXBlICVpbiUgYygiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIpXQpjb25mbGljdF9kb25ldHNrJG5ld19ldmVudF90eXBlWyEoY29uZmxpY3RfZG9uZXRzayRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIlNoZWxsaW5nL2FydGlsbGVyeS9taXNzaWxlIGF0dGFjayIsICJBaXIvZHJvbmUgc3RyaWtlIiwgIkFiZHVjdGlvbi9mb3JjZWQgZGlzYXBwZWFyYW5jZSIgLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiKSldIDwtICJPdGhlciB2aW9sZW5jZSIKYGBgCgpgYGB7cn0KbnVtYmVyX29mX2V2ZW50c19kb25ldHNrIDwtIGNvbmZsaWN0X2RvbmV0c2sgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBuZXdfZXZlbnRfdHlwZSkKYGBgCgpgYGB7cn0KZG9uZXRzayA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgPT0gIkRvbmV0cydrIikKZG9uZXRza19tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPWRvbmV0c2ssICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCmRvbmV0c2tfbWFwCmBgYAoKYGBge3J9CmRvbmV0c2tfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX2RvbmV0c2ssIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBjb2xvcj1uZXdfZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19kb25ldHNrLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1uZXdfZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgMTApKSArCiAgbGFicyhjb2xvciA9ICJTdWItRXZlbnQgVHlwZSIsIHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIlZpb2xlbmNlIHRhcmdldGluZyBDaXZpbGlhbnMgaW4gRG9uZXRzayIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyMgQ29uZmxpY3QgaW4gWmFwb3JpemhpYQoKRHVyaW5nIHRoZSBpbml0aWFsIHN0YWdlcyBvZiB0aGUgaW52YXNpb24sIFJ1c3NpYW4gZm9yY2VzIHN1Y2Nlc3NmdWxseSBvY2N1cGllZCBhIHNpZ25pZmljYW50IHBvcnRpb24gb2YgdGhlIFphcG9yaXpoaWEgcmVnaW9uLiBUaGlzIGluY2x1ZGVkIHRoZSBlbnRpcmUgY29hc3RsaW5lIG9mIHRoZSBTZWEgb2YgQXpvdiwgZW5jb21wYXNzaW5nIHRoZSBVa3JhaW5pYW4gbmF2eSBiYXNlIGluIEJlcmRpYW5zaywgYXMgd2VsbCBhcyBhbiBhcmVhIGV4dGVuZGluZyBmcm9tIEtoZXJzb24gdG8gdGhlIHNvdXRoZXJuIERvbmV0c2sgcmVnaW9ucywgcmVhY2hpbmcgdGhlIERuaXBybyByaXZlci4gVGhlIG9jY3VwYXRpb24gYWxzbyBjb3ZlcmVkIE1lbGl0b3BvbCwgdGhlIHJlZ2lvbidzIHNlY29uZC1sYXJnZXN0IHRvd24uIFVrcmFpbmlhbiBmb3JjZXMgbWFuYWdlZCB0byBoYWx0IHRoZSBhZHZhbmNlbWVudCBvZiBSdXNzaWFuIGZvcmNlcyBpbiB0aGUgT3Jpa2hpdiBhbmQgSHVsaWFpcG9sZSBhcmVhcy4gV2hpbGUgYXBwcm94aW1hdGVseSBoYWxmIG9mIHRoZSBpbmNpZGVudHMgdGFyZ2V0aW5nIGNpdmlsaWFucyBpbiB0aGUgWmFwb3JpemhpYSByZWdpb24gaW52b2x2ZWQgc2hlbGxpbmcsIGFpciBhdHRhY2tzLCBhbmQgZHJvbmUgc3RyaWtlcywgY2l2aWxpYW5zIGhhdmUgYWxzbyBiZWVuIGRpcmVjdGx5IHRhcmdldGVkLiBUaGVzZSBhdHRhY2tzIGluY2x1ZGUgZmlyaW5nIGF0IHZlaGljbGVzIGNhcnJ5aW5nIGV2YWN1YXRpbmcgY2l2aWxpYW5zLCBhcyB3ZWxsIGFzIGluc3RhbmNlcyBvZiB0b3J0dXJlIGFuZCBleGVjdXRpb24uIEluIGFyZWFzIHVuZGVyIFJ1c3NpYW4gb2NjdXBhdGlvbiwgdGhlcmUgYXJlIGZyZXF1ZW50IHJlcG9ydHMgb2YgdGhlIGFiZHVjdGlvbiBvZiBsb2NhbCBvZmZpY2lhbHMsIHRlYWNoZXJzLCBqb3VybmFsaXN0cywgVWtyYWluaWFuIGFybXkgdmV0ZXJhbnMsIGFuZCBjaXZpbCBhY3RpdmlzdHMuCgpgYGB7cn0KY29uZmxpY3RfemFwb3JpemhpYSA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgY2l2aWxpYW5fdGFyZ2V0aW5nICE9ICIiLAogICAgICAgICAgICAgICAgZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGFkbWluMSA9PSAiWmFwb3JpemhpYSIpCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBjYWxsZWQgJ25ld19ldmVudF90eXBlJwpjb25mbGljdF96YXBvcml6aGlhJG5ld19ldmVudF90eXBlIDwtIE5BCgojIE1hcCB2YWx1ZXMgYmFzZWQgb24gJ3N1Yl9ldmVudF90eXBlJwpjb25mbGljdF96YXBvcml6aGlhJG5ld19ldmVudF90eXBlW2NvbmZsaWN0X3phcG9yaXpoaWEkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJBdHRhY2siLCAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIpXSA8LSBjb25mbGljdF96YXBvcml6aGlhJHN1Yl9ldmVudF90eXBlW2NvbmZsaWN0X3phcG9yaXpoaWEkc3ViX2V2ZW50X3R5cGUgJWluJSBjKCJBdHRhY2siLCJTaGVsbGluZy9hcnRpbGxlcnkvbWlzc2lsZSBhdHRhY2siLCAiQWlyL2Ryb25lIHN0cmlrZSIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIlJlbW90ZSBleHBsb3NpdmUvbGFuZG1pbmUvSUVEIildCmNvbmZsaWN0X3phcG9yaXpoaWEkbmV3X2V2ZW50X3R5cGVbIShjb25mbGljdF96YXBvcml6aGlhJHN1Yl9ldmVudF90eXBlICVpbiUgYygiQXR0YWNrIiwiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwgIkFpci9kcm9uZSBzdHJpa2UiLCAiQWJkdWN0aW9uL2ZvcmNlZCBkaXNhcHBlYXJhbmNlIiAsICJSZW1vdGUgZXhwbG9zaXZlL2xhbmRtaW5lL0lFRCIpKV0gPC0gIk90aGVyIHZpb2xlbmNlIgpgYGAKCmBgYHtyfQpudW1iZXJfb2ZfZXZlbnRzX3phcG9yaXpoaWEgPC0gY29uZmxpY3RfemFwb3JpemhpYSAlPiUKICBncm91cF9ieShsb25naXR1ZGUsIGxhdGl0dWRlKSAlPiUKICByZWZyYW1lKG51bWJlcl9vZl9ldmVudHMgPSBuKCksIG5ld19ldmVudF90eXBlKQpgYGAKCmBgYHtyfQp6YXBvcml6aGlhIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSA9PSAiWmFwb3Jpemh6aHlhIikKemFwb3JpemhpYV9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPXphcG9yaXpoaWEsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCnphcG9yaXpoaWFfbWFwCmBgYAoKYGBge3J9CnphcG9yaXpoaWFfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBudW1iZXJfb2ZfZXZlbnRzX3phcG9yaXpoaWEsIGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIHNpemUgPSBudW1iZXJfb2ZfZXZlbnRzLCBjb2xvcj1uZXdfZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c196YXBvcml6aGlhLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1uZXdfZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgMTApKSArCiAgbGFicyhjb2xvciA9ICJTdWItRXZlbnQgVHlwZSIsIHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIlZpb2xlbmNlIHRhcmdldGluZyBDaXZpbGlhbnMgaW4gWmFwb3JpemhpYSIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyBFeHBsb3NpdmUgVGhyZWF0cyBmb3IgQ2l2aWxpYW5zIGluIFNvdXRoZXJuIFVrcmFpbmUKClJ1c3NpYW4gYXR0ZW1wdHMgZm9yIGxhbmRpbmdzIGZyb20gdGhlIEJsYWNrIFNlYSB3ZXJlIHVuc3VjY2Vzc2Z1bC4KUnVzc2lhbiBmb3JjZXMgaW52YWRlZCBzb3V0aGVybiBVa3JhaW5lIGZyb20gdGhlIGFubmV4ZWQgQ3JpbWVhbiBwZW5pbnN1bGEsIHN1Y2Nlc3NmdWxseSBvdmVydGFraW5nIHRoZSBLaGVyc29uIHJlZ2lvbiBhbmQgaXRzIG1haW4gY2l0eSBpbiBNYXJjaCAyMDIyLgpUaGUgS2hlcnNvbiBhbmQgTXlrb2xhaXYgcmVnaW9ucyBleHBlcmllbmNlZCBzaWduaWZpY2FudCB2aW9sZW5jZSwgd2l0aCBhcnRpbGxlcnkgc3RyaWtlcyBsZWFkaW5nIHRvIGhpZ2ggZmF0YWxpdHkgbnVtYmVycy4KVGhlIG1vc3QgY29tbW9uIHR5cGVzIG9mIHZpb2xlbmNlIGluIEtoZXJzb24gd2VyZSBhYmR1Y3Rpb25zLCBmb3JjZWQgZGlzYXBwZWFyYW5jZXMsIHRvcnR1cmUsIHRhcmdldGluZyBwcmltYXJpbHkgb2ZmaWNpYWxzLCBqb3VybmFsaXN0cywgYWN0aXZpc3RzLCBhbmQgdGhvc2Ugc3VzcGVjdGVkIG9mIHByby1Va3JhaW5pYW4gdmlld3MuCkluIEp1bmUgMjAyMiwgUnVzc2lhbiBmb3JjZXMgcmVwb3J0ZWRseSBhYmR1Y3RlZCBhYm91dCA1MCBDcmltZWFuIFRhdGFycyBmcm9tIEtoZXJzb24uClR3byBzaWduaWZpY2FudCBpbmNpZGVudHMgaW4gdGhlIE9kZXNhIHJlZ2lvbiBpbmNsdWRlIGEgbWlzc2lsZSBzdHJpa2UgdGhhdCBraWxsZWQgOCBhbmQgaW5qdXJlZCAxMCBjaXZpbGlhbnMgb24gQXByaWwgMjAyMiwgYW5kIGFuIGFpcnN0cmlrZSB0aGF0IGtpbGxlZCBhdCBsZWFzdCAyMSBjaXZpbGlhbnMgb24gSnVseSAyMDIyLgoKYGBge3J9CnNvdXRoZXJuX3VrcmFpbmVfc3RhdGVzX25hbWUgPSBjKCJNeWtvbGFpdiIsICJLaGVyc29uIiwgIkNyaW1lYSIsICJPZGVzYSIgKQpjb25mbGljdF9zb3V0aGVybl91a3JhaW5lIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoCiAgICAgICAgICAgICAgICBjaXZpbGlhbl90YXJnZXRpbmcgIT0gIiIsCiAgICAgICAgICAgICAgICBldmVudF9kYXRlID49IGFzLkRhdGUoIjIwMjItMDItMDEiKSAmIGV2ZW50X2RhdGUgPD0gYXMuRGF0ZSgiMjAyMy0wMS0zMSIpLAogICAgICAgICAgICAgICAgYWRtaW4xICVpbiUgc291dGhlcm5fdWtyYWluZV9zdGF0ZXNfbmFtZSkKYGBgCgpgYGB7cn0KIyBDcmVhdGUgYSBuZXcgY29sdW1uIGNhbGxlZCAnbmV3X2V2ZW50X3R5cGUnCmNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkbmV3X2V2ZW50X3R5cGUgPC0gTkEKCiMgTWFwIHZhbHVlcyBiYXNlZCBvbiAnc3ViX2V2ZW50X3R5cGUnCmNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkbmV3X2V2ZW50X3R5cGVbY29uZmxpY3Rfc291dGhlcm5fdWtyYWluZSRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIkF0dGFjayIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIlJlbW90ZSBleHBsb3NpdmUvbGFuZG1pbmUvSUVEIildIDwtIGNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkc3ViX2V2ZW50X3R5cGVbY29uZmxpY3Rfc291dGhlcm5fdWtyYWluZSRzdWJfZXZlbnRfdHlwZSAlaW4lIGMoIkF0dGFjayIsICJBYmR1Y3Rpb24vZm9yY2VkIGRpc2FwcGVhcmFuY2UiICwgIlJlbW90ZSBleHBsb3NpdmUvbGFuZG1pbmUvSUVEIildCmNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUkbmV3X2V2ZW50X3R5cGVbIShjb25mbGljdF9zb3V0aGVybl91a3JhaW5lJHN1Yl9ldmVudF90eXBlICVpbiUgYygiQXR0YWNrIiwgIkFiZHVjdGlvbi9mb3JjZWQgZGlzYXBwZWFyYW5jZSIgLCAiUmVtb3RlIGV4cGxvc2l2ZS9sYW5kbWluZS9JRUQiKSldIDwtICJPdGhlciB2aW9sZW5jZSIKYGBgCgpgYGB7cn0KbnVtYmVyX29mX2V2ZW50c19zb3V0aGVybl91a3JhaW5lIDwtIGNvbmZsaWN0X3NvdXRoZXJuX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBuZXdfZXZlbnRfdHlwZSkKYGBgCgpgYGB7cn0Kc291dGhlcm5fdWtyYWluZSA8LSBzdWJzZXQodWtyYWluZV9zdGF0ZXNfcmRzLCBOQU1FXzEgJWluJSBzb3V0aGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCnNvdXRoZXJuX3VrcmFpbmVfbWFwIDwtIGdncGxvdCgpICsKICBnZW9tX3BvbHlnb24oZGF0YT1zb3V0aGVybl91a3JhaW5lLCAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgZmlsbD0ib3JhbmdlIiwgYWxwaGE9MC4yLCBjb2xvcj0iYmxhY2siKSArIGd1aWRlcyhmaWxsID0gIm5vbmUiKSArIHRoZW1lX3ZvaWQoKQpzb3V0aGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpzb3V0aGVybl91a3JhaW5lX21hcCArCiAgZ2VvbV9wb2ludChkYXRhID0gbnVtYmVyX29mX2V2ZW50c19zb3V0aGVybl91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9bmV3X2V2ZW50X3R5cGUpKSArCiAgZ2VvbV9wb2ludChjb2xvcj0iYmxhY2siLCBzaGFwZT0yMSwgZGF0YSA9IG51bWJlcl9vZl9ldmVudHNfc291dGhlcm5fdWtyYWluZSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGZpbGw9bmV3X2V2ZW50X3R5cGUpKSArCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygwLjEsIDEwKSkgKwogIGxhYnMoY29sb3IgPSAiU3ViLUV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJWaW9sZW5jZSB0YXJnZXRpbmcgQ2l2aWxpYW5zIGluIFNvdXRoZXJuIFVrcmFpbmUiLCBmb250ZmFjZT0iYm9sZCIpICsgCiAgbGFicyhzdWJ0aXRsZSA9ICJGZWJydWFyeSAyMDIyIC0gSmFudWFyeSAyMDIzICIpICsKICBjb29yZF9tYXAocHJvamVjdGlvbiA9ICJhbGJlcnMiLCBsYXQwID0gNDksIGxhdDEgPSA1NCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2U9ImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKIyMgQ29uc3RhbnQgTWVuYWNlIGZyb20gdGhlIFNraWVzIGluIENlbnRyYWwgYW5kIFdlc3Rlcm4gVWtyYWluZQoKT3ZlciAxNTAgUnVzc2lhbiBtaXNzaWxlLCBhaXIsIGFuZCBkcm9uZSBzdHJpa2VzIGhhdmUgdGFyZ2V0ZWQgdGhlIENlbnRyYWwgYW5kIFdlc3QgcmVnaW9ucywgcG9zaW5nIGEgc2lnbmlmaWNhbnQgdGhyZWF0IHRvIGNpdmlsaWFuIHNhZmV0eS4KQXBwcm94aW1hdGVseSBvbmUtZmlmdGggb2YgdGhlc2Ugc3RyaWtlcyBoaXQgY2l2aWxpYW4gYXJlYXMsIGxlYWRpbmcgdG8gb3ZlciA4MCBmYXRhbGl0aWVzLgpUd28gaW5jaWRlbnRzIGFjY291bnRlZCBmb3IgbW9zdCBvZiB0aGUgcmVwb3J0ZWQgZmF0YWxpdGllczogYSBtaXNzaWxlIHN0cmlrZSBvbiBhIHNob3BwaW5nIG1hbGwsIGluIFBvbHRhdmEsIG9uIEp1bmUgMjAyMiwgYW5kIGEgbWlzc2lsZSBzdHJpa2Ugb24gYSBWaW5ueXRzaWEgY29uY2VydCBoYWxsIG9uIEp1bHkgMjAyMi4KQXQgbGVhc3QgNTAgUnVzc2lhbiBzdHJpa2VzIHRhcmdldGVkIGVuZXJneSBpbmZyYXN0cnVjdHVyZSBkZWVwIHdpdGhpbiBVa3JhaW5lIHdoaWNoIGNhdXNlZCBwb3dlciBvdXRhZ2VzLCB3aXRoIFZpbm55dHNpYSBiZWluZyBvbmUgb2YgdGhlIG1vc3QgYWZmZWN0ZWQgcmVnaW9ucy4KCmBgYHtyfQp1bmlxdWUoY29uZmxpY3QkYWRtaW4xKQpgYGAKCmBgYHtyfQpjZW50cmFsX3dlc3Rlcm5fdWtyYWluZV9zdGF0ZXNfbmFtZSA8LSAgYygiVm9seW4iLCAiUml2bmUiLCAiTHZpdiIsICJUZXJub3BpbCIsICJLaG1lbG55dHNreWkiLCAiSXZhbm8tRnJhbmtpdnNrIiwgIlpha2FycGF0dGlhIiwgIkNoZXJuaXZ0c2kiLCAiVmlubnl0c2lhIiwgIkNoZXJrYXN5IiwgIktpcm92b2dyYWQiLCAiUG9sdGF2YSIgKQpgYGAKCmBgYHtyfQoKY29uZmxpY3RfY2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUgPC0gY29uZmxpY3QgJT4lCiAgZHBseXI6OmZpbHRlcigKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPj0gYXMuRGF0ZSgiMjAyMi0wMi0wMSIpICYgZXZlbnRfZGF0ZSA8PSBhcy5EYXRlKCIyMDIzLTAxLTMxIiksCiAgICAgICAgICAgICAgICBzdWJfZXZlbnRfdHlwZSA9PSAiU2hlbGxpbmcvYXJ0aWxsZXJ5L21pc3NpbGUgYXR0YWNrIiwKICAgICAgICAgICAgICAgIGFkbWluMSAlaW4lIGNlbnRyYWxfd2VzdGVybl91a3JhaW5lX3N0YXRlc19uYW1lCiAgICAgICAgICAgICAgICApCmBgYAoKYGBge3J9Cm51bWJlcl9vZl9ldmVudHNfY2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUgPC0gY29uZmxpY3RfY2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobGF0aXR1ZGUsIGxvbmdpdHVkZSkgJT4lCiAgc3VtbWFyaXplKG51bWJlcl9vZl9ldmVudHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpCmBgYAoKYGBge3J9CmNlbnRyYWxfd2VzdGVybl91a3JhaW5lIDwtIHN1YnNldCh1a3JhaW5lX3N0YXRlc19yZHMsIE5BTUVfMSAlaW4lIGNlbnRyYWxfdWtyYWluZV9zdGF0ZXNfcmRzX25hbWVzIHwgTkFNRV8xICVpbiUgd2VzdGVybl91a3JhaW5lX3N0YXRlc19yZHNfbmFtZXMpCmNlbnRyYWxfd2VzdGVybl91a3JhaW5lX21hcCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9Y2VudHJhbF93ZXN0ZXJuX3VrcmFpbmUsICBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjIsIGNvbG9yPSJibGFjayIpICsgZ3VpZGVzKGZpbGwgPSAibm9uZSIpICsgdGhlbWVfdm9pZCgpCmNlbnRyYWxfd2VzdGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjZW50cmFsX3dlc3Rlcm5fdWtyYWluZV9tYXAgKwogIGdlb21fcG9pbnQoY29sb3I9ImJsYWNrIiwgc2hhcGU9MjEsIGZpbGw9ImRhcmtibHVlIiwgYWxwaGE9MC42LCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19jZW50cmFsX3dlc3Rlcm5fdWtyYWluZSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMpKSArCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygxLCAxMCksIGd1aWRlID0gJ2xlZ2VuZCcsIGJyZWFrcyA9IGMoMSwgMTAsIDIwLCA1MCksIGxhYmVscyA9IGMoIjEiLCAiMTAiLCAiMjAiLCAiNTArIikpICsKICBsYWJzKHNpemUgPSAiTnVtYmVyIG9mIEV2ZW50cyIpICsKICBsYWJzKHRpdGxlID0gIkxvbmctUmFuZ2UgU3RyaWtlcyBpbiBDZW50cmFsIGFuZCBXZXN0ZXJuIFVrcmFpbmUiLCBmb250ZmFjZT0iYm9sZCIpICsgCiAgbGFicyhzdWJ0aXRsZSA9ICJGZWJydWFyeSAyMDIyIC0gSmFudWFyeSAyMDIzICIpICsKICBjb29yZF9tYXAocHJvamVjdGlvbiA9ICJhbGJlcnMiLCBsYXQwID0gNDksIGxhdDEgPSA1NCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2U9ImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKIyMgSW50ZXJhY3RpdmUgTWFwCgpgYGB7cn0KbGlicmFyeShsZWFmbGV0KQpgYGAKCmBgYHtyfQp1a3JhaW5lX2ludGVyYWN0aXZlX21hcCA8LSBsZWFmbGV0KCkgJT4lCiAgYWRkVGlsZXMoKSAlPiUKICBzZXRWaWV3KGxuZyA9IDM3Ljc5MzMsIGxhdCA9IDQ4LjE0NTAsIHpvb20gPSA3KQp1a3JhaW5lX2ludGVyYWN0aXZlX21hcApgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfc3RhdGVzX25hbWVzID0gbGlzdCgiRG5pcHJvcGV0cm92c2siLCAiTHVoYW5zayIsICJEb25ldHNrIiwgIktoYXJraXYiLCAiWmFwb3JpemhpYSIpCmNvbmZsaWN0X2Vhc3Rlcm5fdWtyYWluZSA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgZXZlbnRfZGF0ZSA+PSBhcy5EYXRlKCIyMDIyLTAyLTAxIikgJiBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjMtMDEtMzEiKSwKICAgICAgICAgICAgICAgIGV2ZW50X3R5cGUgJWluJSBjKCJFeHBsb3Npb25zL1JlbW90ZSB2aW9sZW5jZSIsICJCYXR0bGVzIiwgIlZpb2xlbmNlIGFnYWluc3QgY2l2aWxpYW5zIiksCiAgICAgICAgICAgICAgICBhZG1pbjEgJWluJSBlYXN0ZXJuX3VrcmFpbmVfc3RhdGVzX25hbWVzKQpgYGAKCmBgYHtyfQpldmVudHMgPC0gZGF0YS5mcmFtZShsYXRpdHVkZSA9IGNvbmZsaWN0X2Vhc3Rlcm5fdWtyYWluZSRsYXRpdHVkZSwKICAgICAgICAgICAgICAgICAgICAgbG9uZ2l0dWRlID0gY29uZmxpY3RfZWFzdGVybl91a3JhaW5lJGxvbmdpdHVkZSkKYGBgCgpgYGB7cn0KbSA8LSB1a3JhaW5lX2ludGVyYWN0aXZlX21hcCAlPiUKICBhZGRDaXJjbGVNYXJrZXJzKGRhdGEgPSBldmVudHMsCiAgICAgICAgICAgICAgICAgICBsbmcgPSB+bG9uZ2l0dWRlLAogICAgICAgICAgICAgICAgICAgbGF0ID0gfmxhdGl0dWRlLAogICAgICAgICAgICAgICAgICAgcmFkaXVzID0gMSwKICAgICAgICAgICAgICAgICAgIGNvbG9yID0gInJlZCIsCiAgICAgICAgICAgICAgICAgICBmaWxsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gMC44KQoKIyBEaXNwbGF5IHRoZSBtYXAKbQpgYGAKCmBgYHtyfQptMiA8LSBhZGRQb2x5Z29ucygKICBtYXAgPSBtLAogIGRhdGEgPSBlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcywKICBmaWxsQ29sb3IgPSAib3JhbmdlIiwKICBmaWxsT3BhY2l0eSA9IDAuMiwKICBjb2xvciA9ICJibGFjayIsCiAgd2VpZ2h0ID0gMQopCm0yCmBgYAoKCiMjIENvbmNsdXNpb24KClRoZSB3YXIgaW4gVWtyYWluZSBoYXMgZGlzcnVwdGVkIG5vcm1hbCBsaWZlIGFuZCBkZWZpZWQgZXhwZWN0YXRpb25zIG9mIGEgcXVpY2sgc3VianVnYXRpb24uIFRoZSBhZ2dyZXNzaXZlIGFjdGlvbnMgb2YgUnVzc2lhIGhhdmUgZXhwb3NlZCBtaWxsaW9ucyBvZiBVa3JhaW5pYW5zIHRvIHZpb2xlbmNlIGFuZCBoYXJkc2hpcC4gTWFzcyBncmF2ZXMgaW5kaWNhdGUgcG90ZW50aWFsIGF0cm9jaXRpZXMgaW4gYXJlYXMgdW5kZXIgUnVzc2lhbiBvY2N1cGF0aW9uLiBDb250YW1pbmF0aW9uIG9mIGZvcm1lcmx5IG9jY3VwaWVkIGFyZWFzIHdpdGggbWluZXMgcG9zZXMgYSBzZXJpb3VzIHJpc2sgdG8gcmV0dXJuaW5nIGNpdmlsaWFucy4gVGhlIHdhciBoYXMgbGVkIHRvIGEgY29udHJhY3Rpb24gb2YgVWtyYWluZeKAmXMgZWNvbm9teSBhbmQgaW50ZXJuYWwgYW5kIGV4dGVybmFsIGRpc3BsYWNlbWVudCBvZiBtaWxsaW9ucy4gUmVtYWluaW5nIGNpdmlsaWFucyBmYWNlIG9uZ29pbmcgZGlzcnVwdGlvbnMgdG8gdXRpbGl0aWVzIGFuZCBjb25zdGFudCB0aHJlYXRzIG9mIGNyb3NzLWJvcmRlciBzdHJpa2VzIGFuZCBzaGVsbGluZy4gT25nb2luZyBvY2N1cGF0aW9uIG9mIGEgbnVjbGVhciBwb3dlciBwbGFudCBieSBSdXNzaWEsIGFsb25nIHdpdGggdGhlIHRocmVhdHMgb2YgbnVjbGVhciB3ZWFwb25zLCBwcmVzZW50IGNvbnRpbnVvdXMgcmlza3MgdG8gdGhlIGxpdmVzIGFuZCBlbnZpcm9ubWVudCBvZiBVa3JhaW5lIGFuZCB0aGUgc3Vycm91bmRpbmcgcmVnaW9uLgoKIyMgUHJlLUludmFzaW9uCgpUaGUgRXVyb21haWRhbiBwcm90ZXN0cywgd2hpY2ggc3RhcnRlZCBpbiBsYXRlIDIwMTMsIHdlcmUgcHJpbWFyaWx5IGNlbnRlcmVkIGluIHRoZSBjYXBpdGFsIGNpdHkgb2YgS3lpdiAoS2lldikgYnV0IHNwcmVhZCB0byBvdGhlciByZWdpb25zIGFzIHdlbGwuIFRoZSBwcm90ZXN0cyBpbnZvbHZlZCBjbGFzaGVzIGJldHdlZW4gZGVtb25zdHJhdG9ycyBhbmQgbGF3IGVuZm9yY2VtZW50LCByZXN1bHRpbmcgaW4gaW5zdGFuY2VzIG9mIHZpb2xlbmNlLCBpbmp1cmllcywgYW5kIGZhdGFsaXRpZXMuCgpCZWZvcmUgdGhlIFJ1c3NpYW4gaW52YXNpb24gdGhlIHZpb2xlbmNlIGluIGVhc3Rlcm4gVWtyYWluZSB3YXMgYWxyZWFkeSBjb25jZW50cmF0ZWQgaW4gYXJlYXMgY2xvc2UgdG8gdGhlIFVrcmFpbmlhbi1SdXNzaWFuIGJvcmRlciwgcGFydGljdWxhcmx5IGluIHRoZSBEb25ldHNrIGFuZCBMdWhhbnNrIHJlZ2lvbnMuIENpdGllcyBzdWNoIGFzIERvbmV0c2ssIEx1aGFuc2ssIE1hcml1cG9sLCBhbmQgU2xvdmlhbnNrIHdpdG5lc3NlZCBpbnRlbnNlIGZpZ2h0aW5nIGFuZCBiZWNhbWUgaG90c3BvdHMgb2YgdmlvbGVuY2UuCgpCb3RoIHNpZGVzIG9mIHRoZSBjb25mbGljdCBlbmdhZ2VkIGluIG1pbGl0YXJ5IG9wZXJhdGlvbnMsIGluY2x1ZGluZyBhcnRpbGxlcnkgc2hlbGxpbmcsIHNuaXBlciBhdHRhY2tzLCBhbmQgYXJtZWQgY2xhc2hlcy4gVGhlIHZpb2xlbmNlIHdhcyBub3QgbGltaXRlZCB0byBzcGVjaWZpYyBjaXRpZXMgYnV0IHdhcyBzcHJlYWQgYWNyb3NzIHRoZSBjb25mbGljdC1hZmZlY3RlZCByZWdpb25zLgoKVGhlIGNvbmZsaWN0IHJlc3VsdGVkIGluIGEgc2lnbmlmaWNhbnQgbnVtYmVyIG9mIGNpdmlsaWFuIGNhc3VhbHRpZXMgYW5kIHdpZGVzcHJlYWQgZGlzcGxhY2VtZW50IG9mIHJlc2lkZW50cy4gQ2l2aWxpYW5zLCBpbmNsdWRpbmcgdGhvc2UgbGl2aW5nIGluIHRvd25zIGFuZCB2aWxsYWdlcyBuZWFyIHRoZSBmcm9udCBsaW5lcywgZmFjZWQgdGhlIHJpc2sgb2YgdmlvbGVuY2UgYW5kIHdlcmUgb2Z0ZW4gY2F1Z2h0IGluIHRoZSBjcm9zc2ZpcmUuCgpgYGB7cn0KdWtyYWluZV9tYXAyCmBgYAoKYGBge3J9CmNlbnRyb2lkIDwtIHVrcmFpbmVfc3RhdGVzX3JkcyRjZW50cm9pZCA8LSBjb29yZGluYXRlcyh1a3JhaW5lX3N0YXRlc19yZHMpCnRleHQgPC0gZ2VvbV90ZXh0KGRhdGEgPSAsIGFlcyh4ID0gY2VudHJvaWRbLCAxXSwgeSA9IGNlbnRyb2lkWywgMl0sIGxhYmVsID0gdWtyYWluZV9zdGF0ZXNfcmRzJE5BTUVfMSksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDQpCmBgYAoKYGBge3J9CnBpX3VrcmFpbmVfbWFwIDwtIHVrcmFpbmVfbWFwMiArIAogIGdlb21fdGV4dChhZXMoeCA9IGNlbnRyb2lkWywgMV0sIHkgPSBjZW50cm9pZFssIDJdLCBsYWJlbCA9IHVrcmFpbmVfc3RhdGVzX3Jkc19uYW1lcyksIHNpemU9MikgKyBsYWJzKHRpdGxlID0gIlByZS1JbnZhc2lvbiBDb25mbGljdHMiLCBmb250ZmFjZT0iYm9sZCIpICsgdGhlbWVfdm9pZCgpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpICsgIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KQpwaV91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjb25mbGljdF9waV91a3JhaW5lIDwtIGNvbmZsaWN0ICU+JQogIGRwbHlyOjpmaWx0ZXIoCiAgICAgICAgICAgICAgICBldmVudF9kYXRlIDw9IGFzLkRhdGUoIjIwMjItMDItMDEiKSwKICAgICAgICAgICAgICAgICBjaXZpbGlhbl90YXJnZXRpbmcgIT0gIiIKICAgICAgICAgICAgICAgICkKYGBgCgpgYGB7cn0KbnVtYmVyX29mX2V2ZW50c19waV91a3JhaW5lIDwtIGNvbmZsaWN0X3BpX3VrcmFpbmUgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBldmVudF90eXBlKQpgYGAKCmBgYHtyfQpwaV91a3JhaW5lX21hcCArCiAgZ2VvbV9wb2ludChkYXRhID0gbnVtYmVyX29mX2V2ZW50c19waV91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9ZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gbnVtYmVyX29mX2V2ZW50c19waV91a3JhaW5lLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgZmlsbD1ldmVudF90eXBlKSkgKwogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMC4xLCAxMCkpICsKICBsYWJzKGNvbG9yID0gIkV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJWaW9sZW5jZSB0YXJnZXRpbmcgQ2l2aWxpYW5zIGluIFByZS1JbnZhc2lvbiBVa3JhaW5lIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiQmVmb3JlIEZlYnJ1YXJ5IDIwMjIgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgojIyBQb2xpdGljYWwgVmlvbGVuY2UgaW4gRWFzdGVybiBVa3JhaW5lIFByZS1JbnZhc2lvbgoKYGBge3J9CmNvbmZsaWN0X2Vhc3Rlcm5fdWtyYWluZV9waSA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgZGlzb3JkZXJfdHlwZSA9PSAiUG9saXRpY2FsIHZpb2xlbmNlIiwKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPCBhcy5EYXRlKCIyMDIyLTAyLTAxIiksCiAgICAgICAgICAgICAgICBldmVudF90eXBlICVpbiUgYygiRXhwbG9zaW9ucy9SZW1vdGUgdmlvbGVuY2UiLCAiQmF0dGxlcyIsICJWaW9sZW5jZSBhZ2FpbnN0IGNpdmlsaWFucyIpLAogICAgICAgICAgICAgICAgYWRtaW4xICVpbiUgZWFzdGVybl91a3JhaW5lX3N0YXRlc19uYW1lcykKYGBgCgpgYGB7cn0KZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZV9waSA8LSBjb25mbGljdF9lYXN0ZXJuX3VrcmFpbmVfcGkgJT4lCiAgZ3JvdXBfYnkobG9uZ2l0dWRlLCBsYXRpdHVkZSkgJT4lCiAgcmVmcmFtZShudW1iZXJfb2ZfZXZlbnRzID0gbigpLCBldmVudF90eXBlKQpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwIDwtIGdncGxvdCgpICsKICBnZW9tX3BvbHlnb24oZGF0YT1lYXN0X3VrcmFpbmVfc3RhdGVzX3JkcywgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGZpbGw9Im9yYW5nZSIsIGFscGhhPTAuMiwgY29sb3I9ImJsYWNrIikgKyBndWlkZXMoZmlsbCA9ICJub25lIikgKyB0aGVtZV92b2lkKCkKZWFzdGVybl91a3JhaW5lX21hcApgYGAKCmBgYHtyfQpjZW50cm9pZCA8LSBlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcyRjZW50cm9pZCA8LSBjb29yZGluYXRlcyhlYXN0X3VrcmFpbmVfc3RhdGVzX3JkcykKY2VudHJvaWRbMl0gPSBjZW50cm9pZFsyXSswLjQKY2VudHJvaWRbN10gPSBjZW50cm9pZFs3XS0wLjQKY2VudHJvaWRbM10gPSBjZW50cm9pZFszXS0wLjQKdGV4dCA8LSBnZW9tX3RleHQoZGF0YSA9ICwgYWVzKHggPSBjZW50cm9pZFssIDFdLCB5ID0gY2VudHJvaWRbLCAyXSwgbGFiZWwgPSBjKCJEbmlwcm9wZXRyb3ZzayIsICJEb25ldHNrIiwgIktoYXJraXYiLCAiTHVoYW5zayIsICJaYXBvcml6aGlhIikpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA0KQpgYGAKCmBgYHtyfQplYXN0ZXJuX3VrcmFpbmVfbWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBldmVudF9jb3VudHNfZWFzdGVybl91a3JhaW5lX3BpLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gbnVtYmVyX29mX2V2ZW50cywgY29sb3I9ZXZlbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBkYXRhID0gZXZlbnRfY291bnRzX2Vhc3Rlcm5fdWtyYWluZV9waSwgYWVzKHggPSBsb25naXR1ZGUsIHkgPSBsYXRpdHVkZSwgc2l6ZSA9IG51bWJlcl9vZl9ldmVudHMsIGZpbGw9ZXZlbnRfdHlwZSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDAuMSwgNSkpICsKICBsYWJzKGNvbG9yID0gIkV2ZW50IFR5cGUiLCBzaXplID0gIk51bWJlciBvZiBFdmVudHMiKSArCiAgbGFicyh0aXRsZSA9ICJQb2xpdGljYWwgVmlvbGVuY2UgaW4gRWFzdGVybiBVa3JhaW5lIFByZS1JbnZhc2lvbiIsIGZvbnRmYWNlPSJib2xkIikgKyAKICBsYWJzKHN1YnRpdGxlID0gIkZlYnJ1YXJ5IDIwMjIgLSBKYW51YXJ5IDIwMjMgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZT0iYm9sZCIpLCBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIHRleHQKYGBgCgpgYGB7cn0KY29uZmxpY3RfdWtyYWluZV9waV9yaW90cyA8LSBjb25mbGljdCAlPiUKICBkcGx5cjo6ZmlsdGVyKAogICAgICAgICAgICAgICAgZGlzb3JkZXJfdHlwZSA9PSAiUG9saXRpY2FsIHZpb2xlbmNlIiwKICAgICAgICAgICAgICAgIGV2ZW50X2RhdGUgPCBhcy5EYXRlKCIyMDIyLTAyLTAxIiksCiAgICAgICAgICAgICAgICBldmVudF90eXBlID09ICJSaW90cyIKICAgICAgICAgICAgICAgICkKYGBgCgpgYGB7cn0KdWtyYWluZV9tYXAyICsKICBnZW9tX3BvaW50KGNvbG9yPSJibGFjayIsIHNoYXBlPTIxLCBmaWxsPSJvcmFuZ2UiLCBhbHBoYT0wLjYsIGRhdGEgPSBjb25mbGljdF91a3JhaW5lX3BpX3Jpb3RzLCBhZXMoeCA9IGxvbmdpdHVkZSwgeSA9IGxhdGl0dWRlLCBzaXplID0gMSkpICsKICBsYWJzKHRpdGxlID0gIlJpb3RzIGluIFByZS1JbnZhc2lvbiBVa3JhaW5lIiwgZm9udGZhY2U9ImJvbGQiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiQmVmb3JlIEZlYnJ1YXJ5IDIwMjIgIikgKwogIGNvb3JkX21hcChwcm9qZWN0aW9uID0gImFsYmVycyIsIGxhdDAgPSA0OSwgbGF0MSA9IDU0KSArCiAgZ3VpZGVzKHNpemUgPSAibm9uZSIpICsKICB0aGVtZV92b2lkKCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2U9ImJvbGQiKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAo=